blob: 7d48388493172fc194d013675b34098301afe1c7 [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"
Ezio Melotti16d2b472012-09-18 07:20:18 +0300638 " newline is '' or '\\n', no translation takes place. If newline is any\n"
Victor Stinner401e17d2012-08-04 01:18:56 +0200639 " 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;
Gregory P. Smithb9817b02013-02-01 13:03:39 -08001252 ret = NULL;
1253 do {
1254 ret = PyObject_CallMethodObjArgs(self->buffer,
1255 _PyIO_str_write, b, NULL);
1256 } while (ret == NULL && _PyIO_trap_eintr());
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001257 Py_DECREF(b);
1258 if (ret == NULL)
1259 return -1;
1260 Py_DECREF(ret);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001261 return 0;
1262}
1263
1264static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001265textiowrapper_write(textio *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001266{
1267 PyObject *ret;
1268 PyObject *text; /* owned reference */
1269 PyObject *b;
1270 Py_ssize_t textlen;
1271 int haslf = 0;
1272 int needflush = 0;
1273
1274 CHECK_INITIALIZED(self);
1275
1276 if (!PyArg_ParseTuple(args, "U:write", &text)) {
1277 return NULL;
1278 }
1279
1280 CHECK_CLOSED(self);
1281
Antoine Pitrou0d739d72010-09-05 23:01:12 +00001282 if (self->encoder == NULL)
1283 return _unsupported("not writable");
Benjamin Peterson81971ea2009-05-14 22:01:31 +00001284
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001285 Py_INCREF(text);
1286
1287 textlen = PyUnicode_GetSize(text);
1288
1289 if ((self->writetranslate && self->writenl != NULL) || self->line_buffering)
1290 if (findchar(PyUnicode_AS_UNICODE(text),
1291 PyUnicode_GET_SIZE(text), '\n'))
1292 haslf = 1;
1293
1294 if (haslf && self->writetranslate && self->writenl != NULL) {
1295 PyObject *newtext = PyObject_CallMethod(
1296 text, "replace", "ss", "\n", self->writenl);
1297 Py_DECREF(text);
1298 if (newtext == NULL)
1299 return NULL;
1300 text = newtext;
1301 }
1302
Antoine Pitroue96ec682011-07-23 21:46:35 +02001303 if (self->write_through)
1304 needflush = 1;
1305 else if (self->line_buffering &&
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001306 (haslf ||
1307 findchar(PyUnicode_AS_UNICODE(text),
1308 PyUnicode_GET_SIZE(text), '\r')))
1309 needflush = 1;
1310
1311 /* XXX What if we were just reading? */
Antoine Pitroue4501852009-05-14 18:55:55 +00001312 if (self->encodefunc != NULL) {
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001313 b = (*self->encodefunc)((PyObject *) self, text);
Antoine Pitroue4501852009-05-14 18:55:55 +00001314 self->encoding_start_of_stream = 0;
1315 }
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001316 else
1317 b = PyObject_CallMethodObjArgs(self->encoder,
1318 _PyIO_str_encode, text, NULL);
1319 Py_DECREF(text);
1320 if (b == NULL)
1321 return NULL;
1322
1323 if (self->pending_bytes == NULL) {
1324 self->pending_bytes = PyList_New(0);
1325 if (self->pending_bytes == NULL) {
1326 Py_DECREF(b);
1327 return NULL;
1328 }
1329 self->pending_bytes_count = 0;
1330 }
1331 if (PyList_Append(self->pending_bytes, b) < 0) {
1332 Py_DECREF(b);
1333 return NULL;
1334 }
1335 self->pending_bytes_count += PyBytes_GET_SIZE(b);
1336 Py_DECREF(b);
1337 if (self->pending_bytes_count > self->chunk_size || needflush) {
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001338 if (_textiowrapper_writeflush(self) < 0)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001339 return NULL;
1340 }
Antoine Pitrou24f36292009-03-28 22:16:42 +00001341
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001342 if (needflush) {
1343 ret = PyObject_CallMethodObjArgs(self->buffer, _PyIO_str_flush, NULL);
1344 if (ret == NULL)
1345 return NULL;
1346 Py_DECREF(ret);
1347 }
1348
1349 Py_CLEAR(self->snapshot);
1350
1351 if (self->decoder) {
1352 ret = PyObject_CallMethod(self->decoder, "reset", NULL);
1353 if (ret == NULL)
1354 return NULL;
1355 Py_DECREF(ret);
1356 }
1357
1358 return PyLong_FromSsize_t(textlen);
1359}
1360
1361/* Steal a reference to chars and store it in the decoded_char buffer;
1362 */
1363static void
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001364textiowrapper_set_decoded_chars(textio *self, PyObject *chars)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001365{
1366 Py_CLEAR(self->decoded_chars);
1367 self->decoded_chars = chars;
1368 self->decoded_chars_used = 0;
1369}
1370
1371static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001372textiowrapper_get_decoded_chars(textio *self, Py_ssize_t n)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001373{
1374 PyObject *chars;
1375 Py_ssize_t avail;
1376
1377 if (self->decoded_chars == NULL)
1378 return PyUnicode_FromStringAndSize(NULL, 0);
1379
1380 avail = (PyUnicode_GET_SIZE(self->decoded_chars)
1381 - self->decoded_chars_used);
1382
1383 assert(avail >= 0);
1384
1385 if (n < 0 || n > avail)
1386 n = avail;
1387
1388 if (self->decoded_chars_used > 0 || n < avail) {
1389 chars = PyUnicode_FromUnicode(
1390 PyUnicode_AS_UNICODE(self->decoded_chars)
1391 + self->decoded_chars_used, n);
1392 if (chars == NULL)
1393 return NULL;
1394 }
1395 else {
1396 chars = self->decoded_chars;
1397 Py_INCREF(chars);
1398 }
1399
1400 self->decoded_chars_used += n;
1401 return chars;
1402}
1403
1404/* Read and decode the next chunk of data from the BufferedReader.
1405 */
1406static int
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001407textiowrapper_read_chunk(textio *self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001408{
1409 PyObject *dec_buffer = NULL;
1410 PyObject *dec_flags = NULL;
1411 PyObject *input_chunk = NULL;
1412 PyObject *decoded_chars, *chunk_size;
1413 int eof;
1414
1415 /* The return value is True unless EOF was reached. The decoded string is
1416 * placed in self._decoded_chars (replacing its previous value). The
1417 * entire input chunk is sent to the decoder, though some of it may remain
1418 * buffered in the decoder, yet to be converted.
1419 */
1420
1421 if (self->decoder == NULL) {
Antoine Pitrou0d739d72010-09-05 23:01:12 +00001422 _unsupported("not readable");
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001423 return -1;
1424 }
1425
1426 if (self->telling) {
1427 /* To prepare for tell(), we need to snapshot a point in the file
1428 * where the decoder's input buffer is empty.
1429 */
1430
1431 PyObject *state = PyObject_CallMethodObjArgs(self->decoder,
1432 _PyIO_str_getstate, NULL);
1433 if (state == NULL)
1434 return -1;
1435 /* Given this, we know there was a valid snapshot point
1436 * len(dec_buffer) bytes ago with decoder state (b'', dec_flags).
1437 */
1438 if (PyArg_Parse(state, "(OO)", &dec_buffer, &dec_flags) < 0) {
1439 Py_DECREF(state);
1440 return -1;
1441 }
1442 Py_INCREF(dec_buffer);
1443 Py_INCREF(dec_flags);
1444 Py_DECREF(state);
1445 }
1446
1447 /* Read a chunk, decode it, and put the result in self._decoded_chars. */
1448 chunk_size = PyLong_FromSsize_t(self->chunk_size);
1449 if (chunk_size == NULL)
1450 goto fail;
1451 input_chunk = PyObject_CallMethodObjArgs(self->buffer,
Antoine Pitroue96ec682011-07-23 21:46:35 +02001452 (self->has_read1 ? _PyIO_str_read1: _PyIO_str_read),
1453 chunk_size, NULL);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001454 Py_DECREF(chunk_size);
1455 if (input_chunk == NULL)
1456 goto fail;
1457 assert(PyBytes_Check(input_chunk));
1458
1459 eof = (PyBytes_Size(input_chunk) == 0);
1460
1461 if (Py_TYPE(self->decoder) == &PyIncrementalNewlineDecoder_Type) {
1462 decoded_chars = _PyIncrementalNewlineDecoder_decode(
1463 self->decoder, input_chunk, eof);
1464 }
1465 else {
1466 decoded_chars = PyObject_CallMethodObjArgs(self->decoder,
1467 _PyIO_str_decode, input_chunk, eof ? Py_True : Py_False, NULL);
1468 }
1469
1470 /* TODO sanity check: isinstance(decoded_chars, unicode) */
1471 if (decoded_chars == NULL)
1472 goto fail;
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001473 textiowrapper_set_decoded_chars(self, decoded_chars);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001474 if (PyUnicode_GET_SIZE(decoded_chars) > 0)
1475 eof = 0;
1476
1477 if (self->telling) {
1478 /* At the snapshot point, len(dec_buffer) bytes before the read, the
1479 * next input to be decoded is dec_buffer + input_chunk.
1480 */
1481 PyObject *next_input = PyNumber_Add(dec_buffer, input_chunk);
1482 if (next_input == NULL)
1483 goto fail;
1484 assert (PyBytes_Check(next_input));
1485 Py_DECREF(dec_buffer);
1486 Py_CLEAR(self->snapshot);
1487 self->snapshot = Py_BuildValue("NN", dec_flags, next_input);
1488 }
1489 Py_DECREF(input_chunk);
1490
1491 return (eof == 0);
1492
1493 fail:
1494 Py_XDECREF(dec_buffer);
1495 Py_XDECREF(dec_flags);
1496 Py_XDECREF(input_chunk);
1497 return -1;
1498}
1499
1500static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001501textiowrapper_read(textio *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001502{
1503 Py_ssize_t n = -1;
1504 PyObject *result = NULL, *chunks = NULL;
1505
1506 CHECK_INITIALIZED(self);
1507
Benjamin Petersonbf5ff762009-12-13 19:25:34 +00001508 if (!PyArg_ParseTuple(args, "|O&:read", &_PyIO_ConvertSsize_t, &n))
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001509 return NULL;
1510
1511 CHECK_CLOSED(self);
1512
Antoine Pitrou0d739d72010-09-05 23:01:12 +00001513 if (self->decoder == NULL)
1514 return _unsupported("not readable");
Benjamin Petersona1b49012009-03-31 23:11:32 +00001515
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001516 if (_textiowrapper_writeflush(self) < 0)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001517 return NULL;
1518
1519 if (n < 0) {
1520 /* Read everything */
1521 PyObject *bytes = PyObject_CallMethod(self->buffer, "read", NULL);
1522 PyObject *decoded;
1523 if (bytes == NULL)
1524 goto fail;
1525 decoded = PyObject_CallMethodObjArgs(self->decoder, _PyIO_str_decode,
1526 bytes, Py_True, NULL);
1527 Py_DECREF(bytes);
1528 if (decoded == NULL)
1529 goto fail;
1530
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001531 result = textiowrapper_get_decoded_chars(self, -1);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001532
1533 if (result == NULL) {
1534 Py_DECREF(decoded);
1535 return NULL;
1536 }
1537
1538 PyUnicode_AppendAndDel(&result, decoded);
1539 if (result == NULL)
1540 goto fail;
1541
1542 Py_CLEAR(self->snapshot);
1543 return result;
1544 }
1545 else {
1546 int res = 1;
1547 Py_ssize_t remaining = n;
1548
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001549 result = textiowrapper_get_decoded_chars(self, n);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001550 if (result == NULL)
1551 goto fail;
1552 remaining -= PyUnicode_GET_SIZE(result);
1553
1554 /* Keep reading chunks until we have n characters to return */
1555 while (remaining > 0) {
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001556 res = textiowrapper_read_chunk(self);
Gregory P. Smith51359922012-06-23 23:55:39 -07001557 if (res < 0) {
1558 /* NOTE: PyErr_SetFromErrno() calls PyErr_CheckSignals()
1559 when EINTR occurs so we needn't do it ourselves. */
1560 if (_PyIO_trap_eintr()) {
1561 continue;
1562 }
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001563 goto fail;
Gregory P. Smith51359922012-06-23 23:55:39 -07001564 }
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001565 if (res == 0) /* EOF */
1566 break;
1567 if (chunks == NULL) {
1568 chunks = PyList_New(0);
1569 if (chunks == NULL)
1570 goto fail;
1571 }
1572 if (PyList_Append(chunks, result) < 0)
1573 goto fail;
1574 Py_DECREF(result);
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001575 result = textiowrapper_get_decoded_chars(self, remaining);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001576 if (result == NULL)
1577 goto fail;
1578 remaining -= PyUnicode_GET_SIZE(result);
1579 }
1580 if (chunks != NULL) {
1581 if (result != NULL && PyList_Append(chunks, result) < 0)
1582 goto fail;
1583 Py_CLEAR(result);
1584 result = PyUnicode_Join(_PyIO_empty_str, chunks);
1585 if (result == NULL)
1586 goto fail;
1587 Py_CLEAR(chunks);
1588 }
1589 return result;
1590 }
1591 fail:
1592 Py_XDECREF(result);
1593 Py_XDECREF(chunks);
1594 return NULL;
1595}
1596
1597
1598/* NOTE: `end` must point to the real end of the Py_UNICODE storage,
1599 that is to the NUL character. Otherwise the function will produce
1600 incorrect results. */
1601static Py_UNICODE *
1602find_control_char(Py_UNICODE *start, Py_UNICODE *end, Py_UNICODE ch)
1603{
1604 Py_UNICODE *s = start;
1605 for (;;) {
1606 while (*s > ch)
1607 s++;
1608 if (*s == ch)
1609 return s;
1610 if (s == end)
1611 return NULL;
1612 s++;
1613 }
1614}
1615
1616Py_ssize_t
1617_PyIO_find_line_ending(
1618 int translated, int universal, PyObject *readnl,
1619 Py_UNICODE *start, Py_UNICODE *end, Py_ssize_t *consumed)
1620{
1621 Py_ssize_t len = end - start;
1622
1623 if (translated) {
1624 /* Newlines are already translated, only search for \n */
1625 Py_UNICODE *pos = find_control_char(start, end, '\n');
1626 if (pos != NULL)
1627 return pos - start + 1;
1628 else {
1629 *consumed = len;
1630 return -1;
1631 }
1632 }
1633 else if (universal) {
1634 /* Universal newline search. Find any of \r, \r\n, \n
1635 * The decoder ensures that \r\n are not split in two pieces
1636 */
1637 Py_UNICODE *s = start;
1638 for (;;) {
1639 Py_UNICODE ch;
1640 /* Fast path for non-control chars. The loop always ends
1641 since the Py_UNICODE storage is NUL-terminated. */
1642 while (*s > '\r')
1643 s++;
1644 if (s >= end) {
1645 *consumed = len;
1646 return -1;
1647 }
1648 ch = *s++;
1649 if (ch == '\n')
1650 return s - start;
1651 if (ch == '\r') {
1652 if (*s == '\n')
1653 return s - start + 1;
1654 else
1655 return s - start;
1656 }
1657 }
1658 }
1659 else {
1660 /* Non-universal mode. */
1661 Py_ssize_t readnl_len = PyUnicode_GET_SIZE(readnl);
1662 Py_UNICODE *nl = PyUnicode_AS_UNICODE(readnl);
1663 if (readnl_len == 1) {
1664 Py_UNICODE *pos = find_control_char(start, end, nl[0]);
1665 if (pos != NULL)
1666 return pos - start + 1;
1667 *consumed = len;
1668 return -1;
1669 }
1670 else {
1671 Py_UNICODE *s = start;
1672 Py_UNICODE *e = end - readnl_len + 1;
1673 Py_UNICODE *pos;
1674 if (e < s)
1675 e = s;
1676 while (s < e) {
1677 Py_ssize_t i;
1678 Py_UNICODE *pos = find_control_char(s, end, nl[0]);
1679 if (pos == NULL || pos >= e)
1680 break;
1681 for (i = 1; i < readnl_len; i++) {
1682 if (pos[i] != nl[i])
1683 break;
1684 }
1685 if (i == readnl_len)
1686 return pos - start + readnl_len;
1687 s = pos + 1;
1688 }
1689 pos = find_control_char(e, end, nl[0]);
1690 if (pos == NULL)
1691 *consumed = len;
1692 else
1693 *consumed = pos - start;
1694 return -1;
1695 }
1696 }
1697}
1698
1699static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001700_textiowrapper_readline(textio *self, Py_ssize_t limit)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001701{
1702 PyObject *line = NULL, *chunks = NULL, *remaining = NULL;
1703 Py_ssize_t start, endpos, chunked, offset_to_buffer;
1704 int res;
1705
1706 CHECK_CLOSED(self);
1707
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001708 if (_textiowrapper_writeflush(self) < 0)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001709 return NULL;
1710
1711 chunked = 0;
1712
1713 while (1) {
1714 Py_UNICODE *ptr;
1715 Py_ssize_t line_len;
1716 Py_ssize_t consumed = 0;
1717
1718 /* First, get some data if necessary */
1719 res = 1;
1720 while (!self->decoded_chars ||
1721 !PyUnicode_GET_SIZE(self->decoded_chars)) {
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001722 res = textiowrapper_read_chunk(self);
Gregory P. Smith51359922012-06-23 23:55:39 -07001723 if (res < 0) {
1724 /* NOTE: PyErr_SetFromErrno() calls PyErr_CheckSignals()
1725 when EINTR occurs so we needn't do it ourselves. */
1726 if (_PyIO_trap_eintr()) {
1727 continue;
1728 }
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001729 goto error;
Gregory P. Smith51359922012-06-23 23:55:39 -07001730 }
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001731 if (res == 0)
1732 break;
1733 }
1734 if (res == 0) {
1735 /* end of file */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001736 textiowrapper_set_decoded_chars(self, NULL);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001737 Py_CLEAR(self->snapshot);
1738 start = endpos = offset_to_buffer = 0;
1739 break;
1740 }
1741
1742 if (remaining == NULL) {
1743 line = self->decoded_chars;
1744 start = self->decoded_chars_used;
1745 offset_to_buffer = 0;
1746 Py_INCREF(line);
1747 }
1748 else {
1749 assert(self->decoded_chars_used == 0);
1750 line = PyUnicode_Concat(remaining, self->decoded_chars);
1751 start = 0;
1752 offset_to_buffer = PyUnicode_GET_SIZE(remaining);
1753 Py_CLEAR(remaining);
1754 if (line == NULL)
1755 goto error;
1756 }
1757
1758 ptr = PyUnicode_AS_UNICODE(line);
1759 line_len = PyUnicode_GET_SIZE(line);
1760
1761 endpos = _PyIO_find_line_ending(
1762 self->readtranslate, self->readuniversal, self->readnl,
1763 ptr + start, ptr + line_len, &consumed);
1764 if (endpos >= 0) {
1765 endpos += start;
1766 if (limit >= 0 && (endpos - start) + chunked >= limit)
1767 endpos = start + limit - chunked;
1768 break;
1769 }
1770
1771 /* We can put aside up to `endpos` */
1772 endpos = consumed + start;
1773 if (limit >= 0 && (endpos - start) + chunked >= limit) {
1774 /* Didn't find line ending, but reached length limit */
1775 endpos = start + limit - chunked;
1776 break;
1777 }
1778
1779 if (endpos > start) {
1780 /* No line ending seen yet - put aside current data */
1781 PyObject *s;
1782 if (chunks == NULL) {
1783 chunks = PyList_New(0);
1784 if (chunks == NULL)
1785 goto error;
1786 }
1787 s = PyUnicode_FromUnicode(ptr + start, endpos - start);
1788 if (s == NULL)
1789 goto error;
1790 if (PyList_Append(chunks, s) < 0) {
1791 Py_DECREF(s);
1792 goto error;
1793 }
1794 chunked += PyUnicode_GET_SIZE(s);
1795 Py_DECREF(s);
1796 }
1797 /* There may be some remaining bytes we'll have to prepend to the
1798 next chunk of data */
1799 if (endpos < line_len) {
1800 remaining = PyUnicode_FromUnicode(
1801 ptr + endpos, line_len - endpos);
1802 if (remaining == NULL)
1803 goto error;
1804 }
1805 Py_CLEAR(line);
1806 /* We have consumed the buffer */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001807 textiowrapper_set_decoded_chars(self, NULL);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001808 }
1809
1810 if (line != NULL) {
1811 /* Our line ends in the current buffer */
1812 self->decoded_chars_used = endpos - offset_to_buffer;
1813 if (start > 0 || endpos < PyUnicode_GET_SIZE(line)) {
1814 if (start == 0 && Py_REFCNT(line) == 1) {
1815 if (PyUnicode_Resize(&line, endpos) < 0)
1816 goto error;
1817 }
1818 else {
1819 PyObject *s = PyUnicode_FromUnicode(
1820 PyUnicode_AS_UNICODE(line) + start, endpos - start);
1821 Py_CLEAR(line);
1822 if (s == NULL)
1823 goto error;
1824 line = s;
1825 }
1826 }
1827 }
1828 if (remaining != NULL) {
1829 if (chunks == NULL) {
1830 chunks = PyList_New(0);
1831 if (chunks == NULL)
1832 goto error;
1833 }
1834 if (PyList_Append(chunks, remaining) < 0)
1835 goto error;
1836 Py_CLEAR(remaining);
1837 }
1838 if (chunks != NULL) {
1839 if (line != NULL && PyList_Append(chunks, line) < 0)
1840 goto error;
1841 Py_CLEAR(line);
1842 line = PyUnicode_Join(_PyIO_empty_str, chunks);
1843 if (line == NULL)
1844 goto error;
1845 Py_DECREF(chunks);
1846 }
1847 if (line == NULL)
1848 line = PyUnicode_FromStringAndSize(NULL, 0);
1849
1850 return line;
1851
1852 error:
1853 Py_XDECREF(chunks);
1854 Py_XDECREF(remaining);
1855 Py_XDECREF(line);
1856 return NULL;
1857}
1858
1859static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001860textiowrapper_readline(textio *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001861{
1862 Py_ssize_t limit = -1;
1863
1864 CHECK_INITIALIZED(self);
1865 if (!PyArg_ParseTuple(args, "|n:readline", &limit)) {
1866 return NULL;
1867 }
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001868 return _textiowrapper_readline(self, limit);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001869}
1870
1871/* Seek and Tell */
1872
1873typedef struct {
1874 Py_off_t start_pos;
1875 int dec_flags;
1876 int bytes_to_feed;
1877 int chars_to_skip;
1878 char need_eof;
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001879} cookie_type;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001880
1881/*
1882 To speed up cookie packing/unpacking, we store the fields in a temporary
1883 string and call _PyLong_FromByteArray() or _PyLong_AsByteArray (resp.).
1884 The following macros define at which offsets in the intermediary byte
1885 string the various CookieStruct fields will be stored.
1886 */
1887
1888#define COOKIE_BUF_LEN (sizeof(Py_off_t) + 3 * sizeof(int) + sizeof(char))
1889
1890#if defined(WORDS_BIGENDIAN)
1891
1892# define IS_LITTLE_ENDIAN 0
1893
1894/* We want the least significant byte of start_pos to also be the least
1895 significant byte of the cookie, which means that in big-endian mode we
1896 must copy the fields in reverse order. */
1897
1898# define OFF_START_POS (sizeof(char) + 3 * sizeof(int))
1899# define OFF_DEC_FLAGS (sizeof(char) + 2 * sizeof(int))
1900# define OFF_BYTES_TO_FEED (sizeof(char) + sizeof(int))
1901# define OFF_CHARS_TO_SKIP (sizeof(char))
1902# define OFF_NEED_EOF 0
1903
1904#else
1905
1906# define IS_LITTLE_ENDIAN 1
1907
1908/* Little-endian mode: the least significant byte of start_pos will
1909 naturally end up the least significant byte of the cookie. */
1910
1911# define OFF_START_POS 0
1912# define OFF_DEC_FLAGS (sizeof(Py_off_t))
1913# define OFF_BYTES_TO_FEED (sizeof(Py_off_t) + sizeof(int))
1914# define OFF_CHARS_TO_SKIP (sizeof(Py_off_t) + 2 * sizeof(int))
1915# define OFF_NEED_EOF (sizeof(Py_off_t) + 3 * sizeof(int))
1916
1917#endif
1918
1919static int
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001920textiowrapper_parse_cookie(cookie_type *cookie, PyObject *cookieObj)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001921{
1922 unsigned char buffer[COOKIE_BUF_LEN];
1923 PyLongObject *cookieLong = (PyLongObject *)PyNumber_Long(cookieObj);
1924 if (cookieLong == NULL)
1925 return -1;
1926
1927 if (_PyLong_AsByteArray(cookieLong, buffer, sizeof(buffer),
1928 IS_LITTLE_ENDIAN, 0) < 0) {
1929 Py_DECREF(cookieLong);
1930 return -1;
1931 }
1932 Py_DECREF(cookieLong);
1933
Antoine Pitrou2db74c22009-03-06 21:49:02 +00001934 memcpy(&cookie->start_pos, buffer + OFF_START_POS, sizeof(cookie->start_pos));
1935 memcpy(&cookie->dec_flags, buffer + OFF_DEC_FLAGS, sizeof(cookie->dec_flags));
1936 memcpy(&cookie->bytes_to_feed, buffer + OFF_BYTES_TO_FEED, sizeof(cookie->bytes_to_feed));
1937 memcpy(&cookie->chars_to_skip, buffer + OFF_CHARS_TO_SKIP, sizeof(cookie->chars_to_skip));
1938 memcpy(&cookie->need_eof, buffer + OFF_NEED_EOF, sizeof(cookie->need_eof));
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001939
1940 return 0;
1941}
1942
1943static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001944textiowrapper_build_cookie(cookie_type *cookie)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001945{
1946 unsigned char buffer[COOKIE_BUF_LEN];
1947
Antoine Pitrou2db74c22009-03-06 21:49:02 +00001948 memcpy(buffer + OFF_START_POS, &cookie->start_pos, sizeof(cookie->start_pos));
1949 memcpy(buffer + OFF_DEC_FLAGS, &cookie->dec_flags, sizeof(cookie->dec_flags));
1950 memcpy(buffer + OFF_BYTES_TO_FEED, &cookie->bytes_to_feed, sizeof(cookie->bytes_to_feed));
1951 memcpy(buffer + OFF_CHARS_TO_SKIP, &cookie->chars_to_skip, sizeof(cookie->chars_to_skip));
1952 memcpy(buffer + OFF_NEED_EOF, &cookie->need_eof, sizeof(cookie->need_eof));
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001953
1954 return _PyLong_FromByteArray(buffer, sizeof(buffer), IS_LITTLE_ENDIAN, 0);
1955}
1956#undef IS_LITTLE_ENDIAN
1957
1958static int
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001959_textiowrapper_decoder_setstate(textio *self, cookie_type *cookie)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001960{
1961 PyObject *res;
1962 /* When seeking to the start of the stream, we call decoder.reset()
1963 rather than decoder.getstate().
1964 This is for a few decoders such as utf-16 for which the state value
1965 at start is not (b"", 0) but e.g. (b"", 2) (meaning, in the case of
1966 utf-16, that we are expecting a BOM).
1967 */
1968 if (cookie->start_pos == 0 && cookie->dec_flags == 0)
1969 res = PyObject_CallMethodObjArgs(self->decoder, _PyIO_str_reset, NULL);
1970 else
1971 res = PyObject_CallMethod(self->decoder, "setstate",
1972 "((yi))", "", cookie->dec_flags);
1973 if (res == NULL)
1974 return -1;
1975 Py_DECREF(res);
1976 return 0;
1977}
1978
Antoine Pitroue4501852009-05-14 18:55:55 +00001979static int
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001980_textiowrapper_encoder_setstate(textio *self, cookie_type *cookie)
Antoine Pitroue4501852009-05-14 18:55:55 +00001981{
1982 PyObject *res;
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001983 /* Same as _textiowrapper_decoder_setstate() above. */
Antoine Pitroue4501852009-05-14 18:55:55 +00001984 if (cookie->start_pos == 0 && cookie->dec_flags == 0) {
1985 res = PyObject_CallMethodObjArgs(self->encoder, _PyIO_str_reset, NULL);
1986 self->encoding_start_of_stream = 1;
1987 }
1988 else {
1989 res = PyObject_CallMethodObjArgs(self->encoder, _PyIO_str_setstate,
1990 _PyIO_zero, NULL);
1991 self->encoding_start_of_stream = 0;
1992 }
1993 if (res == NULL)
1994 return -1;
1995 Py_DECREF(res);
1996 return 0;
1997}
1998
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001999static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002000textiowrapper_seek(textio *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002001{
2002 PyObject *cookieObj, *posobj;
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002003 cookie_type cookie;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002004 int whence = 0;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002005 PyObject *res;
2006 int cmp;
2007
2008 CHECK_INITIALIZED(self);
2009
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002010 if (!PyArg_ParseTuple(args, "O|i:seek", &cookieObj, &whence))
2011 return NULL;
2012 CHECK_CLOSED(self);
2013
2014 Py_INCREF(cookieObj);
2015
2016 if (!self->seekable) {
Antoine Pitrou0d739d72010-09-05 23:01:12 +00002017 _unsupported("underlying stream is not seekable");
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002018 goto fail;
2019 }
2020
2021 if (whence == 1) {
2022 /* seek relative to current position */
Antoine Pitroue4501852009-05-14 18:55:55 +00002023 cmp = PyObject_RichCompareBool(cookieObj, _PyIO_zero, Py_EQ);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002024 if (cmp < 0)
2025 goto fail;
2026
2027 if (cmp == 0) {
Antoine Pitrou0d739d72010-09-05 23:01:12 +00002028 _unsupported("can't do nonzero cur-relative seeks");
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002029 goto fail;
2030 }
2031
2032 /* Seeking to the current position should attempt to
2033 * sync the underlying buffer with the current position.
2034 */
2035 Py_DECREF(cookieObj);
2036 cookieObj = PyObject_CallMethod((PyObject *)self, "tell", NULL);
2037 if (cookieObj == NULL)
2038 goto fail;
2039 }
2040 else if (whence == 2) {
2041 /* seek relative to end of file */
2042
Antoine Pitroue4501852009-05-14 18:55:55 +00002043 cmp = PyObject_RichCompareBool(cookieObj, _PyIO_zero, Py_EQ);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002044 if (cmp < 0)
2045 goto fail;
2046
2047 if (cmp == 0) {
Antoine Pitrou0d739d72010-09-05 23:01:12 +00002048 _unsupported("can't do nonzero end-relative seeks");
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002049 goto fail;
2050 }
2051
2052 res = PyObject_CallMethod((PyObject *)self, "flush", NULL);
2053 if (res == NULL)
2054 goto fail;
2055 Py_DECREF(res);
2056
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002057 textiowrapper_set_decoded_chars(self, NULL);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002058 Py_CLEAR(self->snapshot);
2059 if (self->decoder) {
2060 res = PyObject_CallMethod(self->decoder, "reset", NULL);
2061 if (res == NULL)
2062 goto fail;
2063 Py_DECREF(res);
2064 }
2065
2066 res = PyObject_CallMethod(self->buffer, "seek", "ii", 0, 2);
2067 Py_XDECREF(cookieObj);
2068 return res;
2069 }
2070 else if (whence != 0) {
2071 PyErr_Format(PyExc_ValueError,
2072 "invalid whence (%d, should be 0, 1 or 2)", whence);
2073 goto fail;
2074 }
2075
Antoine Pitroue4501852009-05-14 18:55:55 +00002076 cmp = PyObject_RichCompareBool(cookieObj, _PyIO_zero, Py_LT);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002077 if (cmp < 0)
2078 goto fail;
2079
2080 if (cmp == 1) {
2081 PyErr_Format(PyExc_ValueError,
2082 "negative seek position %R", cookieObj);
2083 goto fail;
2084 }
2085
2086 res = PyObject_CallMethodObjArgs((PyObject *)self, _PyIO_str_flush, NULL);
2087 if (res == NULL)
2088 goto fail;
2089 Py_DECREF(res);
2090
2091 /* The strategy of seek() is to go back to the safe start point
2092 * and replay the effect of read(chars_to_skip) from there.
2093 */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002094 if (textiowrapper_parse_cookie(&cookie, cookieObj) < 0)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002095 goto fail;
2096
2097 /* Seek back to the safe start point. */
2098 posobj = PyLong_FromOff_t(cookie.start_pos);
2099 if (posobj == NULL)
2100 goto fail;
2101 res = PyObject_CallMethodObjArgs(self->buffer,
2102 _PyIO_str_seek, posobj, NULL);
2103 Py_DECREF(posobj);
2104 if (res == NULL)
2105 goto fail;
2106 Py_DECREF(res);
2107
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002108 textiowrapper_set_decoded_chars(self, NULL);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002109 Py_CLEAR(self->snapshot);
2110
2111 /* Restore the decoder to its state from the safe start point. */
2112 if (self->decoder) {
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002113 if (_textiowrapper_decoder_setstate(self, &cookie) < 0)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002114 goto fail;
2115 }
2116
2117 if (cookie.chars_to_skip) {
2118 /* Just like _read_chunk, feed the decoder and save a snapshot. */
2119 PyObject *input_chunk = PyObject_CallMethod(
2120 self->buffer, "read", "i", cookie.bytes_to_feed);
2121 PyObject *decoded;
2122
2123 if (input_chunk == NULL)
2124 goto fail;
2125
2126 assert (PyBytes_Check(input_chunk));
2127
2128 self->snapshot = Py_BuildValue("iN", cookie.dec_flags, input_chunk);
2129 if (self->snapshot == NULL) {
2130 Py_DECREF(input_chunk);
2131 goto fail;
2132 }
2133
2134 decoded = PyObject_CallMethod(self->decoder, "decode",
2135 "Oi", input_chunk, (int)cookie.need_eof);
2136
2137 if (decoded == NULL)
2138 goto fail;
2139
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002140 textiowrapper_set_decoded_chars(self, decoded);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002141
2142 /* Skip chars_to_skip of the decoded characters. */
2143 if (PyUnicode_GetSize(self->decoded_chars) < cookie.chars_to_skip) {
2144 PyErr_SetString(PyExc_IOError, "can't restore logical file position");
2145 goto fail;
2146 }
2147 self->decoded_chars_used = cookie.chars_to_skip;
2148 }
2149 else {
2150 self->snapshot = Py_BuildValue("iy", cookie.dec_flags, "");
2151 if (self->snapshot == NULL)
2152 goto fail;
2153 }
2154
Antoine Pitroue4501852009-05-14 18:55:55 +00002155 /* Finally, reset the encoder (merely useful for proper BOM handling) */
2156 if (self->encoder) {
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002157 if (_textiowrapper_encoder_setstate(self, &cookie) < 0)
Antoine Pitroue4501852009-05-14 18:55:55 +00002158 goto fail;
2159 }
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002160 return cookieObj;
2161 fail:
2162 Py_XDECREF(cookieObj);
2163 return NULL;
2164
2165}
2166
2167static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002168textiowrapper_tell(textio *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002169{
2170 PyObject *res;
2171 PyObject *posobj = NULL;
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002172 cookie_type cookie = {0,0,0,0,0};
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002173 PyObject *next_input;
2174 Py_ssize_t chars_to_skip, chars_decoded;
2175 PyObject *saved_state = NULL;
2176 char *input, *input_end;
2177
2178 CHECK_INITIALIZED(self);
2179 CHECK_CLOSED(self);
2180
2181 if (!self->seekable) {
Antoine Pitrou0d739d72010-09-05 23:01:12 +00002182 _unsupported("underlying stream is not seekable");
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002183 goto fail;
2184 }
2185 if (!self->telling) {
2186 PyErr_SetString(PyExc_IOError,
2187 "telling position disabled by next() call");
2188 goto fail;
2189 }
2190
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002191 if (_textiowrapper_writeflush(self) < 0)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002192 return NULL;
2193 res = PyObject_CallMethod((PyObject *)self, "flush", NULL);
2194 if (res == NULL)
2195 goto fail;
2196 Py_DECREF(res);
2197
2198 posobj = PyObject_CallMethod(self->buffer, "tell", NULL);
2199 if (posobj == NULL)
2200 goto fail;
2201
2202 if (self->decoder == NULL || self->snapshot == NULL) {
2203 assert (self->decoded_chars == NULL || PyUnicode_GetSize(self->decoded_chars) == 0);
2204 return posobj;
2205 }
2206
2207#if defined(HAVE_LARGEFILE_SUPPORT)
2208 cookie.start_pos = PyLong_AsLongLong(posobj);
2209#else
2210 cookie.start_pos = PyLong_AsLong(posobj);
2211#endif
2212 if (PyErr_Occurred())
2213 goto fail;
2214
2215 /* Skip backward to the snapshot point (see _read_chunk). */
2216 if (!PyArg_Parse(self->snapshot, "(iO)", &cookie.dec_flags, &next_input))
2217 goto fail;
2218
2219 assert (PyBytes_Check(next_input));
2220
2221 cookie.start_pos -= PyBytes_GET_SIZE(next_input);
2222
2223 /* How many decoded characters have been used up since the snapshot? */
2224 if (self->decoded_chars_used == 0) {
2225 /* We haven't moved from the snapshot point. */
2226 Py_DECREF(posobj);
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002227 return textiowrapper_build_cookie(&cookie);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002228 }
2229
2230 chars_to_skip = self->decoded_chars_used;
2231
2232 /* Starting from the snapshot position, we will walk the decoder
2233 * forward until it gives us enough decoded characters.
2234 */
2235 saved_state = PyObject_CallMethodObjArgs(self->decoder,
2236 _PyIO_str_getstate, NULL);
2237 if (saved_state == NULL)
2238 goto fail;
2239
2240 /* Note our initial start point. */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002241 if (_textiowrapper_decoder_setstate(self, &cookie) < 0)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002242 goto fail;
2243
2244 /* Feed the decoder one byte at a time. As we go, note the
2245 * nearest "safe start point" before the current location
2246 * (a point where the decoder has nothing buffered, so seek()
2247 * can safely start from there and advance to this location).
2248 */
2249 chars_decoded = 0;
2250 input = PyBytes_AS_STRING(next_input);
2251 input_end = input + PyBytes_GET_SIZE(next_input);
2252 while (input < input_end) {
2253 PyObject *state;
2254 char *dec_buffer;
2255 Py_ssize_t dec_buffer_len;
2256 int dec_flags;
2257
2258 PyObject *decoded = PyObject_CallMethod(
2259 self->decoder, "decode", "y#", input, 1);
2260 if (decoded == NULL)
2261 goto fail;
2262 assert (PyUnicode_Check(decoded));
2263 chars_decoded += PyUnicode_GET_SIZE(decoded);
2264 Py_DECREF(decoded);
2265
2266 cookie.bytes_to_feed += 1;
2267
2268 state = PyObject_CallMethodObjArgs(self->decoder,
2269 _PyIO_str_getstate, NULL);
2270 if (state == NULL)
2271 goto fail;
2272 if (!PyArg_Parse(state, "(y#i)", &dec_buffer, &dec_buffer_len, &dec_flags)) {
2273 Py_DECREF(state);
2274 goto fail;
2275 }
2276 Py_DECREF(state);
2277
2278 if (dec_buffer_len == 0 && chars_decoded <= chars_to_skip) {
2279 /* Decoder buffer is empty, so this is a safe start point. */
2280 cookie.start_pos += cookie.bytes_to_feed;
2281 chars_to_skip -= chars_decoded;
2282 cookie.dec_flags = dec_flags;
2283 cookie.bytes_to_feed = 0;
2284 chars_decoded = 0;
2285 }
2286 if (chars_decoded >= chars_to_skip)
2287 break;
2288 input++;
2289 }
2290 if (input == input_end) {
2291 /* We didn't get enough decoded data; signal EOF to get more. */
2292 PyObject *decoded = PyObject_CallMethod(
2293 self->decoder, "decode", "yi", "", /* final = */ 1);
2294 if (decoded == NULL)
2295 goto fail;
2296 assert (PyUnicode_Check(decoded));
2297 chars_decoded += PyUnicode_GET_SIZE(decoded);
2298 Py_DECREF(decoded);
2299 cookie.need_eof = 1;
2300
2301 if (chars_decoded < chars_to_skip) {
2302 PyErr_SetString(PyExc_IOError,
2303 "can't reconstruct logical file position");
2304 goto fail;
2305 }
2306 }
2307
2308 /* finally */
2309 Py_XDECREF(posobj);
2310 res = PyObject_CallMethod(self->decoder, "setstate", "(O)", saved_state);
2311 Py_DECREF(saved_state);
2312 if (res == NULL)
2313 return NULL;
2314 Py_DECREF(res);
2315
2316 /* The returned cookie corresponds to the last safe start point. */
2317 cookie.chars_to_skip = Py_SAFE_DOWNCAST(chars_to_skip, Py_ssize_t, int);
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002318 return textiowrapper_build_cookie(&cookie);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002319
2320 fail:
2321 Py_XDECREF(posobj);
2322 if (saved_state) {
2323 PyObject *type, *value, *traceback;
2324 PyErr_Fetch(&type, &value, &traceback);
2325
2326 res = PyObject_CallMethod(self->decoder, "setstate", "(O)", saved_state);
2327 Py_DECREF(saved_state);
2328 if (res == NULL)
2329 return NULL;
2330 Py_DECREF(res);
2331
2332 PyErr_Restore(type, value, traceback);
2333 }
2334 return NULL;
2335}
2336
2337static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002338textiowrapper_truncate(textio *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002339{
2340 PyObject *pos = Py_None;
2341 PyObject *res;
2342
2343 CHECK_INITIALIZED(self)
2344 if (!PyArg_ParseTuple(args, "|O:truncate", &pos)) {
2345 return NULL;
2346 }
2347
2348 res = PyObject_CallMethodObjArgs((PyObject *) self, _PyIO_str_flush, NULL);
2349 if (res == NULL)
2350 return NULL;
2351 Py_DECREF(res);
2352
Antoine Pitrou905a2ff2010-01-31 22:47:27 +00002353 return PyObject_CallMethodObjArgs(self->buffer, _PyIO_str_truncate, pos, NULL);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002354}
2355
Benjamin Petersonc4c0eae2009-03-09 00:07:03 +00002356static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002357textiowrapper_repr(textio *self)
Benjamin Petersonc4c0eae2009-03-09 00:07:03 +00002358{
Antoine Pitroua4815ca2011-01-09 20:38:15 +00002359 PyObject *nameobj, *modeobj, *res, *s;
Antoine Pitrou716c4442009-05-23 19:04:03 +00002360
2361 CHECK_INITIALIZED(self);
2362
Antoine Pitroua4815ca2011-01-09 20:38:15 +00002363 res = PyUnicode_FromString("<_io.TextIOWrapper");
2364 if (res == NULL)
2365 return NULL;
Antoine Pitrou716c4442009-05-23 19:04:03 +00002366 nameobj = PyObject_GetAttrString((PyObject *) self, "name");
2367 if (nameobj == NULL) {
2368 if (PyErr_ExceptionMatches(PyExc_AttributeError))
2369 PyErr_Clear();
2370 else
Antoine Pitroua4815ca2011-01-09 20:38:15 +00002371 goto error;
Antoine Pitrou716c4442009-05-23 19:04:03 +00002372 }
2373 else {
Antoine Pitroua4815ca2011-01-09 20:38:15 +00002374 s = PyUnicode_FromFormat(" name=%R", nameobj);
Antoine Pitrou716c4442009-05-23 19:04:03 +00002375 Py_DECREF(nameobj);
Antoine Pitroua4815ca2011-01-09 20:38:15 +00002376 if (s == NULL)
2377 goto error;
2378 PyUnicode_AppendAndDel(&res, s);
2379 if (res == NULL)
2380 return NULL;
Antoine Pitrou716c4442009-05-23 19:04:03 +00002381 }
Antoine Pitroua4815ca2011-01-09 20:38:15 +00002382 modeobj = PyObject_GetAttrString((PyObject *) self, "mode");
2383 if (modeobj == NULL) {
2384 if (PyErr_ExceptionMatches(PyExc_AttributeError))
2385 PyErr_Clear();
2386 else
2387 goto error;
2388 }
2389 else {
2390 s = PyUnicode_FromFormat(" mode=%R", modeobj);
2391 Py_DECREF(modeobj);
2392 if (s == NULL)
2393 goto error;
2394 PyUnicode_AppendAndDel(&res, s);
2395 if (res == NULL)
2396 return NULL;
2397 }
2398 s = PyUnicode_FromFormat("%U encoding=%R>",
2399 res, self->encoding);
2400 Py_DECREF(res);
2401 return s;
2402error:
2403 Py_XDECREF(res);
2404 return NULL;
Benjamin Petersonc4c0eae2009-03-09 00:07:03 +00002405}
2406
2407
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002408/* Inquiries */
2409
2410static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002411textiowrapper_fileno(textio *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002412{
2413 CHECK_INITIALIZED(self);
2414 return PyObject_CallMethod(self->buffer, "fileno", NULL);
2415}
2416
2417static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002418textiowrapper_seekable(textio *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002419{
2420 CHECK_INITIALIZED(self);
2421 return PyObject_CallMethod(self->buffer, "seekable", NULL);
2422}
2423
2424static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002425textiowrapper_readable(textio *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002426{
2427 CHECK_INITIALIZED(self);
2428 return PyObject_CallMethod(self->buffer, "readable", NULL);
2429}
2430
2431static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002432textiowrapper_writable(textio *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002433{
2434 CHECK_INITIALIZED(self);
2435 return PyObject_CallMethod(self->buffer, "writable", NULL);
2436}
2437
2438static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002439textiowrapper_isatty(textio *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002440{
2441 CHECK_INITIALIZED(self);
2442 return PyObject_CallMethod(self->buffer, "isatty", NULL);
2443}
2444
2445static PyObject *
Antoine Pitrou243757e2010-11-05 21:15:39 +00002446textiowrapper_getstate(textio *self, PyObject *args)
2447{
2448 PyErr_Format(PyExc_TypeError,
2449 "cannot serialize '%s' object", Py_TYPE(self)->tp_name);
2450 return NULL;
2451}
2452
2453static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002454textiowrapper_flush(textio *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002455{
2456 CHECK_INITIALIZED(self);
2457 CHECK_CLOSED(self);
2458 self->telling = self->seekable;
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002459 if (_textiowrapper_writeflush(self) < 0)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002460 return NULL;
2461 return PyObject_CallMethod(self->buffer, "flush", NULL);
2462}
2463
2464static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002465textiowrapper_close(textio *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002466{
2467 PyObject *res;
Antoine Pitrou6be88762010-05-03 16:48:20 +00002468 int r;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002469 CHECK_INITIALIZED(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002470
Antoine Pitrou6be88762010-05-03 16:48:20 +00002471 res = textiowrapper_closed_get(self, NULL);
2472 if (res == NULL)
2473 return NULL;
2474 r = PyObject_IsTrue(res);
2475 Py_DECREF(res);
2476 if (r < 0)
2477 return NULL;
Victor Stinnerf6c57832010-05-19 01:17:01 +00002478
Antoine Pitrou6be88762010-05-03 16:48:20 +00002479 if (r > 0) {
2480 Py_RETURN_NONE; /* stream already closed */
2481 }
2482 else {
Antoine Pitroue033e062010-10-29 10:38:18 +00002483 if (self->deallocating) {
2484 res = PyObject_CallMethod(self->buffer, "_dealloc_warn", "O", self);
2485 if (res)
2486 Py_DECREF(res);
2487 else
2488 PyErr_Clear();
2489 }
Antoine Pitrou6be88762010-05-03 16:48:20 +00002490 res = PyObject_CallMethod((PyObject *)self, "flush", NULL);
2491 if (res == NULL) {
2492 return NULL;
2493 }
2494 else
2495 Py_DECREF(res);
2496
2497 return PyObject_CallMethod(self->buffer, "close", NULL);
2498 }
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002499}
2500
2501static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002502textiowrapper_iternext(textio *self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002503{
2504 PyObject *line;
2505
2506 CHECK_INITIALIZED(self);
2507
2508 self->telling = 0;
2509 if (Py_TYPE(self) == &PyTextIOWrapper_Type) {
2510 /* Skip method call overhead for speed */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002511 line = _textiowrapper_readline(self, -1);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002512 }
2513 else {
2514 line = PyObject_CallMethodObjArgs((PyObject *)self,
2515 _PyIO_str_readline, NULL);
2516 if (line && !PyUnicode_Check(line)) {
2517 PyErr_Format(PyExc_IOError,
2518 "readline() should have returned an str object, "
2519 "not '%.200s'", Py_TYPE(line)->tp_name);
2520 Py_DECREF(line);
2521 return NULL;
2522 }
2523 }
2524
2525 if (line == NULL)
2526 return NULL;
2527
2528 if (PyUnicode_GET_SIZE(line) == 0) {
2529 /* Reached EOF or would have blocked */
2530 Py_DECREF(line);
2531 Py_CLEAR(self->snapshot);
2532 self->telling = self->seekable;
2533 return NULL;
2534 }
2535
2536 return line;
2537}
2538
2539static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002540textiowrapper_name_get(textio *self, void *context)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002541{
2542 CHECK_INITIALIZED(self);
2543 return PyObject_GetAttrString(self->buffer, "name");
2544}
2545
2546static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002547textiowrapper_closed_get(textio *self, void *context)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002548{
2549 CHECK_INITIALIZED(self);
2550 return PyObject_GetAttr(self->buffer, _PyIO_str_closed);
2551}
2552
2553static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002554textiowrapper_newlines_get(textio *self, void *context)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002555{
2556 PyObject *res;
2557 CHECK_INITIALIZED(self);
2558 if (self->decoder == NULL)
2559 Py_RETURN_NONE;
2560 res = PyObject_GetAttr(self->decoder, _PyIO_str_newlines);
2561 if (res == NULL) {
Benjamin Peterson2cfca792009-06-06 20:46:48 +00002562 if (PyErr_ExceptionMatches(PyExc_AttributeError)) {
2563 PyErr_Clear();
2564 Py_RETURN_NONE;
2565 }
2566 else {
2567 return NULL;
2568 }
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002569 }
2570 return res;
2571}
2572
2573static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002574textiowrapper_errors_get(textio *self, void *context)
Benjamin Peterson0926ad12009-06-06 18:02:12 +00002575{
2576 CHECK_INITIALIZED(self);
2577 return PyUnicode_FromString(PyBytes_AS_STRING(self->errors));
2578}
2579
2580static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002581textiowrapper_chunk_size_get(textio *self, void *context)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002582{
2583 CHECK_INITIALIZED(self);
2584 return PyLong_FromSsize_t(self->chunk_size);
2585}
2586
2587static int
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002588textiowrapper_chunk_size_set(textio *self, PyObject *arg, void *context)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002589{
2590 Py_ssize_t n;
2591 CHECK_INITIALIZED_INT(self);
Antoine Pitroucb4ae812011-07-13 21:07:49 +02002592 n = PyNumber_AsSsize_t(arg, PyExc_ValueError);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002593 if (n == -1 && PyErr_Occurred())
2594 return -1;
2595 if (n <= 0) {
2596 PyErr_SetString(PyExc_ValueError,
2597 "a strictly positive integer is required");
2598 return -1;
2599 }
2600 self->chunk_size = n;
2601 return 0;
2602}
2603
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002604static PyMethodDef textiowrapper_methods[] = {
2605 {"detach", (PyCFunction)textiowrapper_detach, METH_NOARGS},
2606 {"write", (PyCFunction)textiowrapper_write, METH_VARARGS},
2607 {"read", (PyCFunction)textiowrapper_read, METH_VARARGS},
2608 {"readline", (PyCFunction)textiowrapper_readline, METH_VARARGS},
2609 {"flush", (PyCFunction)textiowrapper_flush, METH_NOARGS},
2610 {"close", (PyCFunction)textiowrapper_close, METH_NOARGS},
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002611
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002612 {"fileno", (PyCFunction)textiowrapper_fileno, METH_NOARGS},
2613 {"seekable", (PyCFunction)textiowrapper_seekable, METH_NOARGS},
2614 {"readable", (PyCFunction)textiowrapper_readable, METH_NOARGS},
2615 {"writable", (PyCFunction)textiowrapper_writable, METH_NOARGS},
2616 {"isatty", (PyCFunction)textiowrapper_isatty, METH_NOARGS},
Antoine Pitrou243757e2010-11-05 21:15:39 +00002617 {"__getstate__", (PyCFunction)textiowrapper_getstate, METH_NOARGS},
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002618
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002619 {"seek", (PyCFunction)textiowrapper_seek, METH_VARARGS},
2620 {"tell", (PyCFunction)textiowrapper_tell, METH_NOARGS},
2621 {"truncate", (PyCFunction)textiowrapper_truncate, METH_VARARGS},
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002622 {NULL, NULL}
2623};
2624
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002625static PyMemberDef textiowrapper_members[] = {
2626 {"encoding", T_OBJECT, offsetof(textio, encoding), READONLY},
2627 {"buffer", T_OBJECT, offsetof(textio, buffer), READONLY},
2628 {"line_buffering", T_BOOL, offsetof(textio, line_buffering), READONLY},
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002629 {NULL}
2630};
2631
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002632static PyGetSetDef textiowrapper_getset[] = {
2633 {"name", (getter)textiowrapper_name_get, NULL, NULL},
2634 {"closed", (getter)textiowrapper_closed_get, NULL, NULL},
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002635/* {"mode", (getter)TextIOWrapper_mode_get, NULL, NULL},
2636*/
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002637 {"newlines", (getter)textiowrapper_newlines_get, NULL, NULL},
2638 {"errors", (getter)textiowrapper_errors_get, NULL, NULL},
2639 {"_CHUNK_SIZE", (getter)textiowrapper_chunk_size_get,
2640 (setter)textiowrapper_chunk_size_set, NULL},
Benjamin Peterson1fea3212009-04-19 03:15:20 +00002641 {NULL}
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002642};
2643
2644PyTypeObject PyTextIOWrapper_Type = {
2645 PyVarObject_HEAD_INIT(NULL, 0)
2646 "_io.TextIOWrapper", /*tp_name*/
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002647 sizeof(textio), /*tp_basicsize*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002648 0, /*tp_itemsize*/
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002649 (destructor)textiowrapper_dealloc, /*tp_dealloc*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002650 0, /*tp_print*/
2651 0, /*tp_getattr*/
Benjamin Petersonc4c0eae2009-03-09 00:07:03 +00002652 0, /*tps_etattr*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002653 0, /*tp_compare */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002654 (reprfunc)textiowrapper_repr,/*tp_repr*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002655 0, /*tp_as_number*/
2656 0, /*tp_as_sequence*/
2657 0, /*tp_as_mapping*/
2658 0, /*tp_hash */
2659 0, /*tp_call*/
2660 0, /*tp_str*/
2661 0, /*tp_getattro*/
2662 0, /*tp_setattro*/
2663 0, /*tp_as_buffer*/
2664 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE
2665 | Py_TPFLAGS_HAVE_GC, /*tp_flags*/
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002666 textiowrapper_doc, /* tp_doc */
2667 (traverseproc)textiowrapper_traverse, /* tp_traverse */
2668 (inquiry)textiowrapper_clear, /* tp_clear */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002669 0, /* tp_richcompare */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002670 offsetof(textio, weakreflist), /*tp_weaklistoffset*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002671 0, /* tp_iter */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002672 (iternextfunc)textiowrapper_iternext, /* tp_iternext */
2673 textiowrapper_methods, /* tp_methods */
2674 textiowrapper_members, /* tp_members */
2675 textiowrapper_getset, /* tp_getset */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002676 0, /* tp_base */
2677 0, /* tp_dict */
2678 0, /* tp_descr_get */
2679 0, /* tp_descr_set */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002680 offsetof(textio, dict), /*tp_dictoffset*/
2681 (initproc)textiowrapper_init, /* tp_init */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002682 0, /* tp_alloc */
2683 PyType_GenericNew, /* tp_new */
2684};