blob: 9981d4c3ba32c63d57bfb125f9bba12080e3d155 [file] [log] [blame]
Antoine Pitrou19690592009-06-12 20:14:08 +00001/*
2 An implementation of Text I/O as defined by PEP 3116 - "New I/O"
3
4 Classes defined here: TextIOBase, IncrementalNewlineDecoder, TextIOWrapper.
5
6 Written by Amaury Forgeot d'Arc and Antoine Pitrou
7*/
8
9#define PY_SSIZE_T_CLEAN
10#include "Python.h"
11#include "structmember.h"
12#include "_iomodule.h"
13
14/* TextIOBase */
15
16PyDoc_STRVAR(textiobase_doc,
17 "Base class for text I/O.\n"
18 "\n"
19 "This class provides a character and line based interface to stream\n"
20 "I/O. There is no readinto method because Python's character strings\n"
21 "are immutable. There is no public constructor.\n"
22 );
23
24static PyObject *
25_unsupported(const char *message)
26{
27 PyErr_SetString(_PyIO_unsupported_operation, message);
28 return NULL;
29}
30
31PyDoc_STRVAR(textiobase_detach_doc,
32 "Separate the underlying buffer from the TextIOBase and return it.\n"
33 "\n"
34 "After the underlying buffer has been detached, the TextIO is in an\n"
35 "unusable state.\n"
36 );
37
38static PyObject *
39textiobase_detach(PyObject *self)
40{
41 return _unsupported("detach");
42}
43
44PyDoc_STRVAR(textiobase_read_doc,
45 "Read at most n characters from stream.\n"
46 "\n"
47 "Read from underlying buffer until we have n characters or we hit EOF.\n"
48 "If n is negative or omitted, read until EOF.\n"
49 );
50
51static PyObject *
52textiobase_read(PyObject *self, PyObject *args)
53{
54 return _unsupported("read");
55}
56
57PyDoc_STRVAR(textiobase_readline_doc,
58 "Read until newline or EOF.\n"
59 "\n"
60 "Returns an empty string if EOF is hit immediately.\n"
61 );
62
63static PyObject *
64textiobase_readline(PyObject *self, PyObject *args)
65{
66 return _unsupported("readline");
67}
68
69PyDoc_STRVAR(textiobase_write_doc,
70 "Write string to stream.\n"
71 "Returns the number of characters written (which is always equal to\n"
72 "the length of the string).\n"
73 );
74
75static PyObject *
76textiobase_write(PyObject *self, PyObject *args)
77{
78 return _unsupported("write");
79}
80
81PyDoc_STRVAR(textiobase_encoding_doc,
82 "Encoding of the text stream.\n"
83 "\n"
84 "Subclasses should override.\n"
85 );
86
87static PyObject *
88textiobase_encoding_get(PyObject *self, void *context)
89{
90 Py_RETURN_NONE;
91}
92
93PyDoc_STRVAR(textiobase_newlines_doc,
94 "Line endings translated so far.\n"
95 "\n"
96 "Only line endings translated during reading are considered.\n"
97 "\n"
98 "Subclasses should override.\n"
99 );
100
101static PyObject *
102textiobase_newlines_get(PyObject *self, void *context)
103{
104 Py_RETURN_NONE;
105}
106
107PyDoc_STRVAR(textiobase_errors_doc,
108 "The error setting of the decoder or encoder.\n"
109 "\n"
110 "Subclasses should override.\n"
111 );
112
113static PyObject *
114textiobase_errors_get(PyObject *self, void *context)
115{
116 Py_RETURN_NONE;
117}
118
119
120static 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},
125 {NULL, NULL}
126};
127
128static PyGetSetDef textiobase_getset[] = {
129 {"encoding", (getter)textiobase_encoding_get, NULL, textiobase_encoding_doc},
130 {"newlines", (getter)textiobase_newlines_get, NULL, textiobase_newlines_doc},
131 {"errors", (getter)textiobase_errors_get, NULL, textiobase_errors_doc},
132 {NULL}
133};
134
135PyTypeObject PyTextIOBase_Type = {
136 PyVarObject_HEAD_INIT(NULL, 0)
137 "_io._TextIOBase", /*tp_name*/
138 0, /*tp_basicsize*/
139 0, /*tp_itemsize*/
140 0, /*tp_dealloc*/
141 0, /*tp_print*/
142 0, /*tp_getattr*/
143 0, /*tp_setattr*/
144 0, /*tp_compare */
145 0, /*tp_repr*/
146 0, /*tp_as_number*/
147 0, /*tp_as_sequence*/
148 0, /*tp_as_mapping*/
149 0, /*tp_hash */
150 0, /*tp_call*/
151 0, /*tp_str*/
152 0, /*tp_getattro*/
153 0, /*tp_setattro*/
154 0, /*tp_as_buffer*/
155 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /*tp_flags*/
156 textiobase_doc, /* tp_doc */
157 0, /* tp_traverse */
158 0, /* tp_clear */
159 0, /* tp_richcompare */
160 0, /* tp_weaklistoffset */
161 0, /* tp_iter */
162 0, /* tp_iternext */
163 textiobase_methods, /* tp_methods */
164 0, /* tp_members */
165 textiobase_getset, /* tp_getset */
166 &PyIOBase_Type, /* tp_base */
167 0, /* tp_dict */
168 0, /* tp_descr_get */
169 0, /* tp_descr_set */
170 0, /* tp_dictoffset */
171 0, /* tp_init */
172 0, /* tp_alloc */
173 0, /* tp_new */
174};
175
176
177/* IncrementalNewlineDecoder */
178
179PyDoc_STRVAR(incrementalnewlinedecoder_doc,
180 "Codec used when reading a file in universal newlines mode. It wraps\n"
181 "another incremental decoder, translating \\r\\n and \\r into \\n. It also\n"
182 "records the types of newlines encountered. When used with\n"
183 "translate=False, it ensures that the newline sequence is returned in\n"
184 "one piece. When used with decoder=None, it expects unicode strings as\n"
185 "decode input and translates newlines without first invoking an external\n"
186 "decoder.\n"
187 );
188
189typedef struct {
190 PyObject_HEAD
191 PyObject *decoder;
192 PyObject *errors;
Antoine Pitrou2a466582009-09-21 21:17:48 +0000193 signed int pendingcr: 1;
194 signed int translate: 1;
195 unsigned int seennl: 3;
Antoine Pitrou19690592009-06-12 20:14:08 +0000196} nldecoder_object;
197
198static int
199incrementalnewlinedecoder_init(nldecoder_object *self,
200 PyObject *args, PyObject *kwds)
201{
202 PyObject *decoder;
203 int translate;
204 PyObject *errors = NULL;
205 char *kwlist[] = {"decoder", "translate", "errors", NULL};
206
207 if (!PyArg_ParseTupleAndKeywords(args, kwds, "Oi|O:IncrementalNewlineDecoder",
208 kwlist, &decoder, &translate, &errors))
209 return -1;
210
211 self->decoder = decoder;
212 Py_INCREF(decoder);
213
214 if (errors == NULL) {
215 self->errors = PyUnicode_FromString("strict");
216 if (self->errors == NULL)
217 return -1;
218 }
219 else {
220 Py_INCREF(errors);
221 self->errors = errors;
222 }
223
224 self->translate = translate;
225 self->seennl = 0;
226 self->pendingcr = 0;
227
228 return 0;
229}
230
231static void
232incrementalnewlinedecoder_dealloc(nldecoder_object *self)
233{
234 Py_CLEAR(self->decoder);
235 Py_CLEAR(self->errors);
236 Py_TYPE(self)->tp_free((PyObject *)self);
237}
238
Serhiy Storchaka354d50e2013-02-03 17:10:42 +0200239static int
240check_decoded(PyObject *decoded)
241{
242 if (decoded == NULL)
243 return -1;
244 if (!PyUnicode_Check(decoded)) {
245 PyErr_Format(PyExc_TypeError,
246 "decoder should return a string result, not '%.200s'",
247 Py_TYPE(decoded)->tp_name);
248 Py_DECREF(decoded);
249 return -1;
250 }
251 return 0;
252}
253
Antoine Pitrou19690592009-06-12 20:14:08 +0000254#define SEEN_CR 1
255#define SEEN_LF 2
256#define SEEN_CRLF 4
257#define SEEN_ALL (SEEN_CR | SEEN_LF | SEEN_CRLF)
258
259PyObject *
260_PyIncrementalNewlineDecoder_decode(PyObject *_self,
261 PyObject *input, int final)
262{
263 PyObject *output;
264 Py_ssize_t output_len;
265 nldecoder_object *self = (nldecoder_object *) _self;
266
267 if (self->decoder == NULL) {
268 PyErr_SetString(PyExc_ValueError,
269 "IncrementalNewlineDecoder.__init__ not called");
270 return NULL;
271 }
272
273 /* decode input (with the eventual \r from a previous pass) */
274 if (self->decoder != Py_None) {
275 output = PyObject_CallMethodObjArgs(self->decoder,
276 _PyIO_str_decode, input, final ? Py_True : Py_False, NULL);
277 }
278 else {
279 output = input;
280 Py_INCREF(output);
281 }
282
Serhiy Storchaka354d50e2013-02-03 17:10:42 +0200283 if (check_decoded(output) < 0)
Antoine Pitrou19690592009-06-12 20:14:08 +0000284 return NULL;
285
Antoine Pitrou19690592009-06-12 20:14:08 +0000286 output_len = PyUnicode_GET_SIZE(output);
287 if (self->pendingcr && (final || output_len > 0)) {
288 Py_UNICODE *out;
289 PyObject *modified = PyUnicode_FromUnicode(NULL, output_len + 1);
290 if (modified == NULL)
291 goto error;
292 out = PyUnicode_AS_UNICODE(modified);
293 out[0] = '\r';
294 memcpy(out + 1, PyUnicode_AS_UNICODE(output),
295 output_len * sizeof(Py_UNICODE));
296 Py_DECREF(output);
297 output = modified;
298 self->pendingcr = 0;
299 output_len++;
300 }
301
302 /* retain last \r even when not translating data:
303 * then readline() is sure to get \r\n in one pass
304 */
305 if (!final) {
306 if (output_len > 0
307 && PyUnicode_AS_UNICODE(output)[output_len - 1] == '\r') {
308
309 if (Py_REFCNT(output) == 1) {
310 if (PyUnicode_Resize(&output, output_len - 1) < 0)
311 goto error;
312 }
313 else {
314 PyObject *modified = PyUnicode_FromUnicode(
315 PyUnicode_AS_UNICODE(output),
316 output_len - 1);
317 if (modified == NULL)
318 goto error;
319 Py_DECREF(output);
320 output = modified;
321 }
322 self->pendingcr = 1;
323 }
324 }
325
326 /* Record which newlines are read and do newline translation if desired,
327 all in one pass. */
328 {
329 Py_UNICODE *in_str;
330 Py_ssize_t len;
331 int seennl = self->seennl;
332 int only_lf = 0;
333
334 in_str = PyUnicode_AS_UNICODE(output);
335 len = PyUnicode_GET_SIZE(output);
336
337 if (len == 0)
338 return output;
339
340 /* If, up to now, newlines are consistently \n, do a quick check
341 for the \r *byte* with the libc's optimized memchr.
342 */
343 if (seennl == SEEN_LF || seennl == 0) {
344 only_lf = (memchr(in_str, '\r', len * sizeof(Py_UNICODE)) == NULL);
345 }
346
347 if (only_lf) {
348 /* If not already seen, quick scan for a possible "\n" character.
349 (there's nothing else to be done, even when in translation mode)
350 */
351 if (seennl == 0 &&
352 memchr(in_str, '\n', len * sizeof(Py_UNICODE)) != NULL) {
353 Py_UNICODE *s, *end;
354 s = in_str;
355 end = in_str + len;
356 for (;;) {
357 Py_UNICODE c;
358 /* Fast loop for non-control characters */
359 while (*s > '\n')
360 s++;
361 c = *s++;
362 if (c == '\n') {
363 seennl |= SEEN_LF;
364 break;
365 }
366 if (s > end)
367 break;
368 }
369 }
370 /* Finished: we have scanned for newlines, and none of them
371 need translating */
372 }
373 else if (!self->translate) {
374 Py_UNICODE *s, *end;
375 /* We have already seen all newline types, no need to scan again */
376 if (seennl == SEEN_ALL)
377 goto endscan;
378 s = in_str;
379 end = in_str + len;
380 for (;;) {
381 Py_UNICODE c;
382 /* Fast loop for non-control characters */
383 while (*s > '\r')
384 s++;
385 c = *s++;
386 if (c == '\n')
387 seennl |= SEEN_LF;
388 else if (c == '\r') {
389 if (*s == '\n') {
390 seennl |= SEEN_CRLF;
391 s++;
392 }
393 else
394 seennl |= SEEN_CR;
395 }
396 if (s > end)
397 break;
398 if (seennl == SEEN_ALL)
399 break;
400 }
401 endscan:
402 ;
403 }
404 else {
405 PyObject *translated = NULL;
406 Py_UNICODE *out_str;
407 Py_UNICODE *in, *out, *end;
408 if (Py_REFCNT(output) != 1) {
409 /* We could try to optimize this so that we only do a copy
410 when there is something to translate. On the other hand,
411 most decoders should only output non-shared strings, i.e.
412 translation is done in place. */
413 translated = PyUnicode_FromUnicode(NULL, len);
414 if (translated == NULL)
415 goto error;
416 assert(Py_REFCNT(translated) == 1);
417 memcpy(PyUnicode_AS_UNICODE(translated),
418 PyUnicode_AS_UNICODE(output),
419 len * sizeof(Py_UNICODE));
420 }
421 else {
422 translated = output;
423 }
424 out_str = PyUnicode_AS_UNICODE(translated);
425 in = in_str;
426 out = out_str;
427 end = in_str + len;
428 for (;;) {
429 Py_UNICODE c;
430 /* Fast loop for non-control characters */
431 while ((c = *in++) > '\r')
432 *out++ = c;
433 if (c == '\n') {
434 *out++ = c;
435 seennl |= SEEN_LF;
436 continue;
437 }
438 if (c == '\r') {
439 if (*in == '\n') {
440 in++;
441 seennl |= SEEN_CRLF;
442 }
443 else
444 seennl |= SEEN_CR;
445 *out++ = '\n';
446 continue;
447 }
448 if (in > end)
449 break;
450 *out++ = c;
451 }
452 if (translated != output) {
453 Py_DECREF(output);
454 output = translated;
455 }
456 if (out - out_str != len) {
457 if (PyUnicode_Resize(&output, out - out_str) < 0)
458 goto error;
459 }
460 }
461 self->seennl |= seennl;
462 }
463
464 return output;
465
466 error:
467 Py_DECREF(output);
468 return NULL;
469}
470
471static PyObject *
472incrementalnewlinedecoder_decode(nldecoder_object *self,
473 PyObject *args, PyObject *kwds)
474{
475 char *kwlist[] = {"input", "final", NULL};
476 PyObject *input;
477 int final = 0;
478
479 if (!PyArg_ParseTupleAndKeywords(args, kwds, "O|i:IncrementalNewlineDecoder",
480 kwlist, &input, &final))
481 return NULL;
482 return _PyIncrementalNewlineDecoder_decode((PyObject *) self, input, final);
483}
484
485static PyObject *
486incrementalnewlinedecoder_getstate(nldecoder_object *self, PyObject *args)
487{
488 PyObject *buffer;
489 unsigned PY_LONG_LONG flag;
490
491 if (self->decoder != Py_None) {
492 PyObject *state = PyObject_CallMethodObjArgs(self->decoder,
493 _PyIO_str_getstate, NULL);
494 if (state == NULL)
495 return NULL;
496 if (!PyArg_Parse(state, "(OK)", &buffer, &flag)) {
497 Py_DECREF(state);
498 return NULL;
499 }
500 Py_INCREF(buffer);
501 Py_DECREF(state);
502 }
503 else {
504 buffer = PyBytes_FromString("");
505 flag = 0;
506 }
507 flag <<= 1;
508 if (self->pendingcr)
509 flag |= 1;
510 return Py_BuildValue("NK", buffer, flag);
511}
512
513static PyObject *
514incrementalnewlinedecoder_setstate(nldecoder_object *self, PyObject *state)
515{
516 PyObject *buffer;
517 unsigned PY_LONG_LONG flag;
518
519 if (!PyArg_Parse(state, "(OK)", &buffer, &flag))
520 return NULL;
521
522 self->pendingcr = (int) flag & 1;
523 flag >>= 1;
524
525 if (self->decoder != Py_None)
526 return PyObject_CallMethod(self->decoder,
527 "setstate", "((OK))", buffer, flag);
528 else
529 Py_RETURN_NONE;
530}
531
532static PyObject *
533incrementalnewlinedecoder_reset(nldecoder_object *self, PyObject *args)
534{
535 self->seennl = 0;
536 self->pendingcr = 0;
537 if (self->decoder != Py_None)
538 return PyObject_CallMethodObjArgs(self->decoder, _PyIO_str_reset, NULL);
539 else
540 Py_RETURN_NONE;
541}
542
543static PyObject *
544incrementalnewlinedecoder_newlines_get(nldecoder_object *self, void *context)
545{
546 switch (self->seennl) {
547 case SEEN_CR:
548 return PyUnicode_FromString("\r");
549 case SEEN_LF:
550 return PyUnicode_FromString("\n");
551 case SEEN_CRLF:
552 return PyUnicode_FromString("\r\n");
553 case SEEN_CR | SEEN_LF:
554 return Py_BuildValue("ss", "\r", "\n");
555 case SEEN_CR | SEEN_CRLF:
556 return Py_BuildValue("ss", "\r", "\r\n");
557 case SEEN_LF | SEEN_CRLF:
558 return Py_BuildValue("ss", "\n", "\r\n");
559 case SEEN_CR | SEEN_LF | SEEN_CRLF:
560 return Py_BuildValue("sss", "\r", "\n", "\r\n");
561 default:
562 Py_RETURN_NONE;
563 }
564
565}
566
567
568static PyMethodDef incrementalnewlinedecoder_methods[] = {
569 {"decode", (PyCFunction)incrementalnewlinedecoder_decode, METH_VARARGS|METH_KEYWORDS},
570 {"getstate", (PyCFunction)incrementalnewlinedecoder_getstate, METH_NOARGS},
571 {"setstate", (PyCFunction)incrementalnewlinedecoder_setstate, METH_O},
572 {"reset", (PyCFunction)incrementalnewlinedecoder_reset, METH_NOARGS},
573 {NULL}
574};
575
576static PyGetSetDef incrementalnewlinedecoder_getset[] = {
577 {"newlines", (getter)incrementalnewlinedecoder_newlines_get, NULL, NULL},
578 {NULL}
579};
580
581PyTypeObject PyIncrementalNewlineDecoder_Type = {
582 PyVarObject_HEAD_INIT(NULL, 0)
583 "_io.IncrementalNewlineDecoder", /*tp_name*/
584 sizeof(nldecoder_object), /*tp_basicsize*/
585 0, /*tp_itemsize*/
586 (destructor)incrementalnewlinedecoder_dealloc, /*tp_dealloc*/
587 0, /*tp_print*/
588 0, /*tp_getattr*/
589 0, /*tp_setattr*/
590 0, /*tp_compare */
591 0, /*tp_repr*/
592 0, /*tp_as_number*/
593 0, /*tp_as_sequence*/
594 0, /*tp_as_mapping*/
595 0, /*tp_hash */
596 0, /*tp_call*/
597 0, /*tp_str*/
598 0, /*tp_getattro*/
599 0, /*tp_setattro*/
600 0, /*tp_as_buffer*/
601 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /*tp_flags*/
602 incrementalnewlinedecoder_doc, /* tp_doc */
603 0, /* tp_traverse */
604 0, /* tp_clear */
605 0, /* tp_richcompare */
606 0, /*tp_weaklistoffset*/
607 0, /* tp_iter */
608 0, /* tp_iternext */
609 incrementalnewlinedecoder_methods, /* tp_methods */
610 0, /* tp_members */
611 incrementalnewlinedecoder_getset, /* tp_getset */
612 0, /* tp_base */
613 0, /* tp_dict */
614 0, /* tp_descr_get */
615 0, /* tp_descr_set */
616 0, /* tp_dictoffset */
617 (initproc)incrementalnewlinedecoder_init, /* tp_init */
618 0, /* tp_alloc */
619 PyType_GenericNew, /* tp_new */
620};
621
622
623/* TextIOWrapper */
624
625PyDoc_STRVAR(textiowrapper_doc,
626 "Character and line based layer over a BufferedIOBase object, buffer.\n"
627 "\n"
628 "encoding gives the name of the encoding that the stream will be\n"
629 "decoded or encoded with. It defaults to locale.getpreferredencoding.\n"
630 "\n"
631 "errors determines the strictness of encoding and decoding (see the\n"
632 "codecs.register) and defaults to \"strict\".\n"
633 "\n"
Antoine Pitrou76370f42012-08-04 00:55:38 +0200634 "newline controls how line endings are handled. It can be None, '',\n"
635 "'\\n', '\\r', and '\\r\\n'. It works as follows:\n"
636 "\n"
637 "* On input, if newline is None, universal newlines mode is\n"
638 " enabled. Lines in the input can end in '\\n', '\\r', or '\\r\\n', and\n"
639 " these are translated into '\\n' before being returned to the\n"
640 " caller. If it is '', universal newline mode is enabled, but line\n"
641 " endings are returned to the caller untranslated. If it has any of\n"
642 " the other legal values, input lines are only terminated by the given\n"
643 " string, and the line ending is returned to the caller untranslated.\n"
644 "\n"
645 "* On output, if newline is None, any '\\n' characters written are\n"
646 " translated to the system default line separator, os.linesep. If\n"
647 " newline is '', no translation takes place. If newline is any of the\n"
648 " other legal values, any '\\n' characters written are translated to\n"
649 " the given string.\n"
Antoine Pitrou19690592009-06-12 20:14:08 +0000650 "\n"
651 "If line_buffering is True, a call to flush is implied when a call to\n"
652 "write contains a newline character."
653 );
654
655typedef PyObject *
656 (*encodefunc_t)(PyObject *, PyObject *);
657
658typedef struct
659{
660 PyObject_HEAD
661 int ok; /* initialized? */
662 int detached;
663 Py_ssize_t chunk_size;
664 PyObject *buffer;
665 PyObject *encoding;
666 PyObject *encoder;
667 PyObject *decoder;
668 PyObject *readnl;
669 PyObject *errors;
670 const char *writenl; /* utf-8 encoded, NULL stands for \n */
671 char line_buffering;
672 char readuniversal;
673 char readtranslate;
674 char writetranslate;
675 char seekable;
676 char telling;
677 /* Specialized encoding func (see below) */
678 encodefunc_t encodefunc;
679 /* Whether or not it's the start of the stream */
680 char encoding_start_of_stream;
681
682 /* Reads and writes are internally buffered in order to speed things up.
683 However, any read will first flush the write buffer if itsn't empty.
684
685 Please also note that text to be written is first encoded before being
686 buffered. This is necessary so that encoding errors are immediately
687 reported to the caller, but it unfortunately means that the
688 IncrementalEncoder (whose encode() method is always written in Python)
689 becomes a bottleneck for small writes.
690 */
691 PyObject *decoded_chars; /* buffer for text returned from decoder */
692 Py_ssize_t decoded_chars_used; /* offset into _decoded_chars for read() */
693 PyObject *pending_bytes; /* list of bytes objects waiting to be
694 written, or NULL */
695 Py_ssize_t pending_bytes_count;
696 PyObject *snapshot;
697 /* snapshot is either None, or a tuple (dec_flags, next_input) where
698 * dec_flags is the second (integer) item of the decoder state and
699 * next_input is the chunk of input bytes that comes next after the
700 * snapshot point. We use this to reconstruct decoder states in tell().
701 */
702
703 /* Cache raw object if it's a FileIO object */
704 PyObject *raw;
705
706 PyObject *weakreflist;
707 PyObject *dict;
708} textio;
709
710
711/* A couple of specialized cases in order to bypass the slow incremental
712 encoding methods for the most popular encodings. */
713
714static PyObject *
715ascii_encode(textio *self, PyObject *text)
716{
717 return PyUnicode_EncodeASCII(PyUnicode_AS_UNICODE(text),
718 PyUnicode_GET_SIZE(text),
719 PyBytes_AS_STRING(self->errors));
720}
721
722static PyObject *
723utf16be_encode(textio *self, PyObject *text)
724{
725 return PyUnicode_EncodeUTF16(PyUnicode_AS_UNICODE(text),
726 PyUnicode_GET_SIZE(text),
727 PyBytes_AS_STRING(self->errors), 1);
728}
729
730static PyObject *
731utf16le_encode(textio *self, PyObject *text)
732{
733 return PyUnicode_EncodeUTF16(PyUnicode_AS_UNICODE(text),
734 PyUnicode_GET_SIZE(text),
735 PyBytes_AS_STRING(self->errors), -1);
736}
737
738static PyObject *
739utf16_encode(textio *self, PyObject *text)
740{
741 if (!self->encoding_start_of_stream) {
742 /* Skip the BOM and use native byte ordering */
743#if defined(WORDS_BIGENDIAN)
744 return utf16be_encode(self, text);
745#else
746 return utf16le_encode(self, text);
747#endif
748 }
749 return PyUnicode_EncodeUTF16(PyUnicode_AS_UNICODE(text),
750 PyUnicode_GET_SIZE(text),
751 PyBytes_AS_STRING(self->errors), 0);
752}
753
754static PyObject *
755utf32be_encode(textio *self, PyObject *text)
756{
757 return PyUnicode_EncodeUTF32(PyUnicode_AS_UNICODE(text),
758 PyUnicode_GET_SIZE(text),
759 PyBytes_AS_STRING(self->errors), 1);
760}
761
762static PyObject *
763utf32le_encode(textio *self, PyObject *text)
764{
765 return PyUnicode_EncodeUTF32(PyUnicode_AS_UNICODE(text),
766 PyUnicode_GET_SIZE(text),
767 PyBytes_AS_STRING(self->errors), -1);
768}
769
770static PyObject *
771utf32_encode(textio *self, PyObject *text)
772{
773 if (!self->encoding_start_of_stream) {
774 /* Skip the BOM and use native byte ordering */
775#if defined(WORDS_BIGENDIAN)
776 return utf32be_encode(self, text);
777#else
778 return utf32le_encode(self, text);
779#endif
780 }
781 return PyUnicode_EncodeUTF32(PyUnicode_AS_UNICODE(text),
782 PyUnicode_GET_SIZE(text),
783 PyBytes_AS_STRING(self->errors), 0);
784}
785
786static PyObject *
787utf8_encode(textio *self, PyObject *text)
788{
789 return PyUnicode_EncodeUTF8(PyUnicode_AS_UNICODE(text),
790 PyUnicode_GET_SIZE(text),
791 PyBytes_AS_STRING(self->errors));
792}
793
794static PyObject *
795latin1_encode(textio *self, PyObject *text)
796{
797 return PyUnicode_EncodeLatin1(PyUnicode_AS_UNICODE(text),
798 PyUnicode_GET_SIZE(text),
799 PyBytes_AS_STRING(self->errors));
800}
801
802/* Map normalized encoding names onto the specialized encoding funcs */
803
804typedef struct {
805 const char *name;
806 encodefunc_t encodefunc;
807} encodefuncentry;
808
809static encodefuncentry encodefuncs[] = {
810 {"ascii", (encodefunc_t) ascii_encode},
811 {"iso8859-1", (encodefunc_t) latin1_encode},
812 {"utf-8", (encodefunc_t) utf8_encode},
813 {"utf-16-be", (encodefunc_t) utf16be_encode},
814 {"utf-16-le", (encodefunc_t) utf16le_encode},
815 {"utf-16", (encodefunc_t) utf16_encode},
816 {"utf-32-be", (encodefunc_t) utf32be_encode},
817 {"utf-32-le", (encodefunc_t) utf32le_encode},
818 {"utf-32", (encodefunc_t) utf32_encode},
819 {NULL, NULL}
820};
821
822
823static int
824textiowrapper_init(textio *self, PyObject *args, PyObject *kwds)
825{
826 char *kwlist[] = {"buffer", "encoding", "errors",
827 "newline", "line_buffering",
828 NULL};
Serhiy Storchakac7797dc2015-05-31 20:21:00 +0300829 PyObject *buffer, *raw, *codec_info = NULL;
Antoine Pitrou19690592009-06-12 20:14:08 +0000830 char *encoding = NULL;
831 char *errors = NULL;
832 char *newline = NULL;
833 int line_buffering = 0;
834
835 PyObject *res;
836 int r;
837
838 self->ok = 0;
839 self->detached = 0;
840 if (!PyArg_ParseTupleAndKeywords(args, kwds, "O|zzzi:fileio",
841 kwlist, &buffer, &encoding, &errors,
842 &newline, &line_buffering))
843 return -1;
844
845 if (newline && newline[0] != '\0'
846 && !(newline[0] == '\n' && newline[1] == '\0')
847 && !(newline[0] == '\r' && newline[1] == '\0')
848 && !(newline[0] == '\r' && newline[1] == '\n' && newline[2] == '\0')) {
849 PyErr_Format(PyExc_ValueError,
850 "illegal newline value: %s", newline);
851 return -1;
852 }
853
854 Py_CLEAR(self->buffer);
855 Py_CLEAR(self->encoding);
856 Py_CLEAR(self->encoder);
857 Py_CLEAR(self->decoder);
858 Py_CLEAR(self->readnl);
859 Py_CLEAR(self->decoded_chars);
860 Py_CLEAR(self->pending_bytes);
861 Py_CLEAR(self->snapshot);
862 Py_CLEAR(self->errors);
863 Py_CLEAR(self->raw);
864 self->decoded_chars_used = 0;
865 self->pending_bytes_count = 0;
866 self->encodefunc = NULL;
867 self->writenl = NULL;
868
869 if (encoding == NULL && self->encoding == NULL) {
870 if (_PyIO_locale_module == NULL) {
871 _PyIO_locale_module = PyImport_ImportModule("locale");
872 if (_PyIO_locale_module == NULL)
873 goto catch_ImportError;
874 else
875 goto use_locale;
876 }
877 else {
878 use_locale:
879 self->encoding = PyObject_CallMethod(
880 _PyIO_locale_module, "getpreferredencoding", NULL);
881 if (self->encoding == NULL) {
882 catch_ImportError:
883 /*
884 Importing locale can raise a ImportError because of
885 _functools, and locale.getpreferredencoding can raise a
886 ImportError if _locale is not available. These will happen
887 during module building.
888 */
889 if (PyErr_ExceptionMatches(PyExc_ImportError)) {
890 PyErr_Clear();
891 self->encoding = PyString_FromString("ascii");
892 }
893 else
894 goto error;
895 }
896 else if (!PyString_Check(self->encoding))
897 Py_CLEAR(self->encoding);
898 }
899 }
900 if (self->encoding != NULL)
901 encoding = PyString_AsString(self->encoding);
902 else if (encoding != NULL) {
903 self->encoding = PyString_FromString(encoding);
904 if (self->encoding == NULL)
905 goto error;
906 }
907 else {
908 PyErr_SetString(PyExc_IOError,
909 "could not determine default encoding");
910 }
911
Serhiy Storchakac7797dc2015-05-31 20:21:00 +0300912 /* Check we have been asked for a real text encoding */
913 codec_info = _PyCodec_LookupTextEncoding(encoding, "codecs.open()");
914 if (codec_info == NULL) {
915 Py_CLEAR(self->encoding);
916 goto error;
917 }
918
919 /* XXX: Failures beyond this point have the potential to leak elements
920 * of the partially constructed object (like self->encoding)
921 */
922
Antoine Pitrou19690592009-06-12 20:14:08 +0000923 if (errors == NULL)
924 errors = "strict";
925 self->errors = PyBytes_FromString(errors);
926 if (self->errors == NULL)
927 goto error;
928
929 self->chunk_size = 8192;
930 self->readuniversal = (newline == NULL || newline[0] == '\0');
931 self->line_buffering = line_buffering;
932 self->readtranslate = (newline == NULL);
933 if (newline) {
934 self->readnl = PyString_FromString(newline);
935 if (self->readnl == NULL)
Serhiy Storchakac7797dc2015-05-31 20:21:00 +0300936 goto error;
Antoine Pitrou19690592009-06-12 20:14:08 +0000937 }
938 self->writetranslate = (newline == NULL || newline[0] != '\0');
939 if (!self->readuniversal && self->writetranslate) {
940 self->writenl = PyString_AsString(self->readnl);
941 if (!strcmp(self->writenl, "\n"))
942 self->writenl = NULL;
943 }
944#ifdef MS_WINDOWS
945 else
946 self->writenl = "\r\n";
947#endif
948
949 /* Build the decoder object */
950 res = PyObject_CallMethod(buffer, "readable", NULL);
951 if (res == NULL)
952 goto error;
953 r = PyObject_IsTrue(res);
954 Py_DECREF(res);
955 if (r == -1)
956 goto error;
957 if (r == 1) {
Serhiy Storchakac7797dc2015-05-31 20:21:00 +0300958 self->decoder = _PyCodecInfo_GetIncrementalDecoder(codec_info,
959 errors);
Antoine Pitrou19690592009-06-12 20:14:08 +0000960 if (self->decoder == NULL)
961 goto error;
962
963 if (self->readuniversal) {
964 PyObject *incrementalDecoder = PyObject_CallFunction(
965 (PyObject *)&PyIncrementalNewlineDecoder_Type,
966 "Oi", self->decoder, (int)self->readtranslate);
967 if (incrementalDecoder == NULL)
968 goto error;
969 Py_CLEAR(self->decoder);
970 self->decoder = incrementalDecoder;
971 }
972 }
973
974 /* Build the encoder object */
975 res = PyObject_CallMethod(buffer, "writable", NULL);
976 if (res == NULL)
977 goto error;
978 r = PyObject_IsTrue(res);
979 Py_DECREF(res);
980 if (r == -1)
981 goto error;
982 if (r == 1) {
Serhiy Storchakac7797dc2015-05-31 20:21:00 +0300983 self->encoder = _PyCodecInfo_GetIncrementalEncoder(codec_info,
984 errors);
Antoine Pitrou19690592009-06-12 20:14:08 +0000985 if (self->encoder == NULL)
986 goto error;
987 /* Get the normalized named of the codec */
Serhiy Storchakac7797dc2015-05-31 20:21:00 +0300988 res = PyObject_GetAttrString(codec_info, "name");
Antoine Pitrou19690592009-06-12 20:14:08 +0000989 if (res == NULL) {
990 if (PyErr_ExceptionMatches(PyExc_AttributeError))
991 PyErr_Clear();
992 else
993 goto error;
994 }
995 else if (PyString_Check(res)) {
996 encodefuncentry *e = encodefuncs;
997 while (e->name != NULL) {
998 if (!strcmp(PyString_AS_STRING(res), e->name)) {
999 self->encodefunc = e->encodefunc;
1000 break;
1001 }
1002 e++;
1003 }
1004 }
1005 Py_XDECREF(res);
1006 }
1007
Serhiy Storchakac7797dc2015-05-31 20:21:00 +03001008 /* Finished sorting out the codec details */
1009 Py_DECREF(codec_info);
1010
Antoine Pitrou19690592009-06-12 20:14:08 +00001011 self->buffer = buffer;
1012 Py_INCREF(buffer);
1013
1014 if (Py_TYPE(buffer) == &PyBufferedReader_Type ||
1015 Py_TYPE(buffer) == &PyBufferedWriter_Type ||
1016 Py_TYPE(buffer) == &PyBufferedRandom_Type) {
1017 raw = PyObject_GetAttrString(buffer, "raw");
1018 /* Cache the raw FileIO object to speed up 'closed' checks */
1019 if (raw == NULL) {
1020 if (PyErr_ExceptionMatches(PyExc_AttributeError))
1021 PyErr_Clear();
1022 else
1023 goto error;
1024 }
1025 else if (Py_TYPE(raw) == &PyFileIO_Type)
1026 self->raw = raw;
1027 else
1028 Py_DECREF(raw);
1029 }
1030
1031 res = PyObject_CallMethod(buffer, "seekable", NULL);
1032 if (res == NULL)
1033 goto error;
Antoine Pitrouc5bef752012-08-15 23:16:51 +02001034 r = PyObject_IsTrue(res);
Antoine Pitrou19690592009-06-12 20:14:08 +00001035 Py_DECREF(res);
Antoine Pitrouc5bef752012-08-15 23:16:51 +02001036 if (r < 0)
1037 goto error;
1038 self->seekable = self->telling = r;
Antoine Pitrou19690592009-06-12 20:14:08 +00001039
1040 self->encoding_start_of_stream = 0;
1041 if (self->seekable && self->encoder) {
1042 PyObject *cookieObj;
1043 int cmp;
1044
1045 self->encoding_start_of_stream = 1;
1046
1047 cookieObj = PyObject_CallMethodObjArgs(buffer, _PyIO_str_tell, NULL);
1048 if (cookieObj == NULL)
1049 goto error;
1050
1051 cmp = PyObject_RichCompareBool(cookieObj, _PyIO_zero, Py_EQ);
1052 Py_DECREF(cookieObj);
1053 if (cmp < 0) {
1054 goto error;
1055 }
1056
1057 if (cmp == 0) {
1058 self->encoding_start_of_stream = 0;
1059 res = PyObject_CallMethodObjArgs(self->encoder, _PyIO_str_setstate,
1060 _PyIO_zero, NULL);
1061 if (res == NULL)
1062 goto error;
1063 Py_DECREF(res);
1064 }
1065 }
1066
1067 self->ok = 1;
1068 return 0;
1069
1070 error:
Serhiy Storchakac7797dc2015-05-31 20:21:00 +03001071 Py_XDECREF(codec_info);
Antoine Pitrou19690592009-06-12 20:14:08 +00001072 return -1;
1073}
1074
1075static int
1076_textiowrapper_clear(textio *self)
1077{
1078 if (self->ok && _PyIOBase_finalize((PyObject *) self) < 0)
1079 return -1;
1080 self->ok = 0;
1081 Py_CLEAR(self->buffer);
1082 Py_CLEAR(self->encoding);
1083 Py_CLEAR(self->encoder);
1084 Py_CLEAR(self->decoder);
1085 Py_CLEAR(self->readnl);
1086 Py_CLEAR(self->decoded_chars);
1087 Py_CLEAR(self->pending_bytes);
1088 Py_CLEAR(self->snapshot);
1089 Py_CLEAR(self->errors);
1090 Py_CLEAR(self->raw);
1091 return 0;
1092}
1093
1094static void
1095textiowrapper_dealloc(textio *self)
1096{
1097 if (_textiowrapper_clear(self) < 0)
1098 return;
1099 _PyObject_GC_UNTRACK(self);
1100 if (self->weakreflist != NULL)
1101 PyObject_ClearWeakRefs((PyObject *)self);
1102 Py_CLEAR(self->dict);
1103 Py_TYPE(self)->tp_free((PyObject *)self);
1104}
1105
1106static int
1107textiowrapper_traverse(textio *self, visitproc visit, void *arg)
1108{
1109 Py_VISIT(self->buffer);
1110 Py_VISIT(self->encoding);
1111 Py_VISIT(self->encoder);
1112 Py_VISIT(self->decoder);
1113 Py_VISIT(self->readnl);
1114 Py_VISIT(self->decoded_chars);
1115 Py_VISIT(self->pending_bytes);
1116 Py_VISIT(self->snapshot);
1117 Py_VISIT(self->errors);
1118 Py_VISIT(self->raw);
1119
1120 Py_VISIT(self->dict);
1121 return 0;
1122}
1123
1124static int
1125textiowrapper_clear(textio *self)
1126{
1127 if (_textiowrapper_clear(self) < 0)
1128 return -1;
1129 Py_CLEAR(self->dict);
1130 return 0;
1131}
1132
1133static PyObject *
1134textiowrapper_closed_get(textio *self, void *context);
1135
1136/* This macro takes some shortcuts to make the common case faster. */
1137#define CHECK_CLOSED(self) \
1138 do { \
1139 int r; \
1140 PyObject *_res; \
1141 if (Py_TYPE(self) == &PyTextIOWrapper_Type) { \
1142 if (self->raw != NULL) \
1143 r = _PyFileIO_closed(self->raw); \
1144 else { \
1145 _res = textiowrapper_closed_get(self, NULL); \
1146 if (_res == NULL) \
1147 return NULL; \
1148 r = PyObject_IsTrue(_res); \
1149 Py_DECREF(_res); \
1150 if (r < 0) \
1151 return NULL; \
1152 } \
1153 if (r > 0) { \
1154 PyErr_SetString(PyExc_ValueError, \
1155 "I/O operation on closed file."); \
1156 return NULL; \
1157 } \
1158 } \
1159 else if (_PyIOBase_check_closed((PyObject *)self, Py_True) == NULL) \
1160 return NULL; \
1161 } while (0)
1162
1163#define CHECK_INITIALIZED(self) \
1164 if (self->ok <= 0) { \
Benjamin Peterson53ae6142014-12-21 20:51:50 -06001165 PyErr_SetString(PyExc_ValueError, \
1166 "I/O operation on uninitialized object"); \
Antoine Pitrou19690592009-06-12 20:14:08 +00001167 return NULL; \
1168 }
1169
Benjamin Peterson53ae6142014-12-21 20:51:50 -06001170#define CHECK_ATTACHED(self) \
1171 CHECK_INITIALIZED(self); \
1172 if (self->detached) { \
1173 PyErr_SetString(PyExc_ValueError, \
1174 "underlying buffer has been detached"); \
1175 return NULL; \
1176 }
1177
1178#define CHECK_ATTACHED_INT(self) \
Antoine Pitrou19690592009-06-12 20:14:08 +00001179 if (self->ok <= 0) { \
Benjamin Peterson53ae6142014-12-21 20:51:50 -06001180 PyErr_SetString(PyExc_ValueError, \
1181 "I/O operation on uninitialized object"); \
1182 return -1; \
1183 } else if (self->detached) { \
1184 PyErr_SetString(PyExc_ValueError, \
1185 "underlying buffer has been detached"); \
Antoine Pitrou19690592009-06-12 20:14:08 +00001186 return -1; \
1187 }
1188
1189
1190static PyObject *
1191textiowrapper_detach(textio *self)
1192{
1193 PyObject *buffer, *res;
Benjamin Peterson53ae6142014-12-21 20:51:50 -06001194 CHECK_ATTACHED(self);
Antoine Pitrou19690592009-06-12 20:14:08 +00001195 res = PyObject_CallMethodObjArgs((PyObject *)self, _PyIO_str_flush, NULL);
1196 if (res == NULL)
1197 return NULL;
1198 Py_DECREF(res);
1199 buffer = self->buffer;
1200 self->buffer = NULL;
1201 self->detached = 1;
Antoine Pitrou19690592009-06-12 20:14:08 +00001202 return buffer;
1203}
1204
1205Py_LOCAL_INLINE(const Py_UNICODE *)
1206findchar(const Py_UNICODE *s, Py_ssize_t size, Py_UNICODE ch)
1207{
1208 /* like wcschr, but doesn't stop at NULL characters */
1209 while (size-- > 0) {
1210 if (*s == ch)
1211 return s;
1212 s++;
1213 }
1214 return NULL;
1215}
1216
1217/* Flush the internal write buffer. This doesn't explicitly flush the
1218 underlying buffered object, though. */
1219static int
1220_textiowrapper_writeflush(textio *self)
1221{
Amaury Forgeot d'Arcfff896b2009-08-29 18:14:40 +00001222 PyObject *pending, *b, *ret;
Antoine Pitrou19690592009-06-12 20:14:08 +00001223
1224 if (self->pending_bytes == NULL)
1225 return 0;
Amaury Forgeot d'Arcfff896b2009-08-29 18:14:40 +00001226
1227 pending = self->pending_bytes;
1228 Py_INCREF(pending);
1229 self->pending_bytes_count = 0;
1230 Py_CLEAR(self->pending_bytes);
1231
1232 b = _PyBytes_Join(_PyIO_empty_bytes, pending);
1233 Py_DECREF(pending);
Antoine Pitrou19690592009-06-12 20:14:08 +00001234 if (b == NULL)
1235 return -1;
Gregory P. Smitha998ad02013-02-01 13:02:59 -08001236 ret = NULL;
1237 do {
1238 ret = PyObject_CallMethodObjArgs(self->buffer,
1239 _PyIO_str_write, b, NULL);
1240 } while (ret == NULL && _PyIO_trap_eintr());
Antoine Pitrou19690592009-06-12 20:14:08 +00001241 Py_DECREF(b);
1242 if (ret == NULL)
1243 return -1;
1244 Py_DECREF(ret);
Antoine Pitrou19690592009-06-12 20:14:08 +00001245 return 0;
1246}
1247
1248static PyObject *
1249textiowrapper_write(textio *self, PyObject *args)
1250{
1251 PyObject *ret;
1252 PyObject *text; /* owned reference */
1253 PyObject *b;
1254 Py_ssize_t textlen;
1255 int haslf = 0;
1256 int needflush = 0;
1257
Benjamin Peterson53ae6142014-12-21 20:51:50 -06001258 CHECK_ATTACHED(self);
Antoine Pitrou19690592009-06-12 20:14:08 +00001259
1260 if (!PyArg_ParseTuple(args, "U:write", &text)) {
1261 return NULL;
1262 }
1263
1264 CHECK_CLOSED(self);
1265
1266 if (self->encoder == NULL) {
1267 PyErr_SetString(PyExc_IOError, "not writable");
1268 return NULL;
1269 }
1270
1271 Py_INCREF(text);
1272
1273 textlen = PyUnicode_GetSize(text);
1274
1275 if ((self->writetranslate && self->writenl != NULL) || self->line_buffering)
1276 if (findchar(PyUnicode_AS_UNICODE(text),
1277 PyUnicode_GET_SIZE(text), '\n'))
1278 haslf = 1;
1279
1280 if (haslf && self->writetranslate && self->writenl != NULL) {
1281 PyObject *newtext = PyObject_CallMethod(
1282 text, "replace", "ss", "\n", self->writenl);
1283 Py_DECREF(text);
1284 if (newtext == NULL)
1285 return NULL;
1286 text = newtext;
1287 }
1288
1289 if (self->line_buffering &&
1290 (haslf ||
1291 findchar(PyUnicode_AS_UNICODE(text),
1292 PyUnicode_GET_SIZE(text), '\r')))
1293 needflush = 1;
1294
1295 /* XXX What if we were just reading? */
1296 if (self->encodefunc != NULL) {
1297 b = (*self->encodefunc)((PyObject *) self, text);
1298 self->encoding_start_of_stream = 0;
1299 }
1300 else
1301 b = PyObject_CallMethodObjArgs(self->encoder,
1302 _PyIO_str_encode, text, NULL);
1303 Py_DECREF(text);
1304 if (b == NULL)
1305 return NULL;
1306
1307 if (self->pending_bytes == NULL) {
1308 self->pending_bytes = PyList_New(0);
1309 if (self->pending_bytes == NULL) {
1310 Py_DECREF(b);
1311 return NULL;
1312 }
1313 self->pending_bytes_count = 0;
1314 }
1315 if (PyList_Append(self->pending_bytes, b) < 0) {
1316 Py_DECREF(b);
1317 return NULL;
1318 }
1319 self->pending_bytes_count += PyBytes_GET_SIZE(b);
1320 Py_DECREF(b);
1321 if (self->pending_bytes_count > self->chunk_size || needflush) {
1322 if (_textiowrapper_writeflush(self) < 0)
1323 return NULL;
1324 }
1325
1326 if (needflush) {
1327 ret = PyObject_CallMethodObjArgs(self->buffer, _PyIO_str_flush, NULL);
1328 if (ret == NULL)
1329 return NULL;
1330 Py_DECREF(ret);
1331 }
1332
1333 Py_CLEAR(self->snapshot);
1334
1335 if (self->decoder) {
1336 ret = PyObject_CallMethod(self->decoder, "reset", NULL);
1337 if (ret == NULL)
1338 return NULL;
1339 Py_DECREF(ret);
1340 }
1341
1342 return PyLong_FromSsize_t(textlen);
1343}
1344
1345/* Steal a reference to chars and store it in the decoded_char buffer;
1346 */
1347static void
1348textiowrapper_set_decoded_chars(textio *self, PyObject *chars)
1349{
1350 Py_CLEAR(self->decoded_chars);
1351 self->decoded_chars = chars;
1352 self->decoded_chars_used = 0;
1353}
1354
1355static PyObject *
1356textiowrapper_get_decoded_chars(textio *self, Py_ssize_t n)
1357{
1358 PyObject *chars;
1359 Py_ssize_t avail;
1360
1361 if (self->decoded_chars == NULL)
1362 return PyUnicode_FromStringAndSize(NULL, 0);
1363
1364 avail = (PyUnicode_GET_SIZE(self->decoded_chars)
1365 - self->decoded_chars_used);
1366
1367 assert(avail >= 0);
1368
1369 if (n < 0 || n > avail)
1370 n = avail;
1371
1372 if (self->decoded_chars_used > 0 || n < avail) {
1373 chars = PyUnicode_FromUnicode(
1374 PyUnicode_AS_UNICODE(self->decoded_chars)
1375 + self->decoded_chars_used, n);
1376 if (chars == NULL)
1377 return NULL;
1378 }
1379 else {
1380 chars = self->decoded_chars;
1381 Py_INCREF(chars);
1382 }
1383
1384 self->decoded_chars_used += n;
1385 return chars;
1386}
1387
1388/* Read and decode the next chunk of data from the BufferedReader.
1389 */
1390static int
1391textiowrapper_read_chunk(textio *self)
1392{
1393 PyObject *dec_buffer = NULL;
1394 PyObject *dec_flags = NULL;
1395 PyObject *input_chunk = NULL;
1396 PyObject *decoded_chars, *chunk_size;
1397 int eof;
1398
1399 /* The return value is True unless EOF was reached. The decoded string is
1400 * placed in self._decoded_chars (replacing its previous value). The
1401 * entire input chunk is sent to the decoder, though some of it may remain
1402 * buffered in the decoder, yet to be converted.
1403 */
1404
1405 if (self->decoder == NULL) {
1406 PyErr_SetString(PyExc_IOError, "not readable");
1407 return -1;
1408 }
1409
1410 if (self->telling) {
1411 /* To prepare for tell(), we need to snapshot a point in the file
1412 * where the decoder's input buffer is empty.
1413 */
1414
1415 PyObject *state = PyObject_CallMethodObjArgs(self->decoder,
1416 _PyIO_str_getstate, NULL);
1417 if (state == NULL)
1418 return -1;
1419 /* Given this, we know there was a valid snapshot point
1420 * len(dec_buffer) bytes ago with decoder state (b'', dec_flags).
1421 */
1422 if (PyArg_Parse(state, "(OO)", &dec_buffer, &dec_flags) < 0) {
1423 Py_DECREF(state);
1424 return -1;
1425 }
1426 Py_INCREF(dec_buffer);
1427 Py_INCREF(dec_flags);
1428 Py_DECREF(state);
1429 }
1430
1431 /* Read a chunk, decode it, and put the result in self._decoded_chars. */
1432 chunk_size = PyLong_FromSsize_t(self->chunk_size);
1433 if (chunk_size == NULL)
1434 goto fail;
1435 input_chunk = PyObject_CallMethodObjArgs(self->buffer,
1436 _PyIO_str_read1, chunk_size, NULL);
1437 Py_DECREF(chunk_size);
1438 if (input_chunk == NULL)
1439 goto fail;
Serhiy Storchaka354d50e2013-02-03 17:10:42 +02001440 if (!PyBytes_Check(input_chunk)) {
1441 PyErr_Format(PyExc_TypeError,
1442 "underlying read1() should have returned a bytes object, "
1443 "not '%.200s'", Py_TYPE(input_chunk)->tp_name);
1444 goto fail;
1445 }
Antoine Pitrou19690592009-06-12 20:14:08 +00001446
1447 eof = (PyBytes_Size(input_chunk) == 0);
1448
1449 if (Py_TYPE(self->decoder) == &PyIncrementalNewlineDecoder_Type) {
1450 decoded_chars = _PyIncrementalNewlineDecoder_decode(
1451 self->decoder, input_chunk, eof);
1452 }
1453 else {
1454 decoded_chars = PyObject_CallMethodObjArgs(self->decoder,
1455 _PyIO_str_decode, input_chunk, eof ? Py_True : Py_False, NULL);
1456 }
1457
Serhiy Storchaka354d50e2013-02-03 17:10:42 +02001458 if (check_decoded(decoded_chars) < 0)
Antoine Pitrou19690592009-06-12 20:14:08 +00001459 goto fail;
1460 textiowrapper_set_decoded_chars(self, decoded_chars);
1461 if (PyUnicode_GET_SIZE(decoded_chars) > 0)
1462 eof = 0;
1463
1464 if (self->telling) {
1465 /* At the snapshot point, len(dec_buffer) bytes before the read, the
1466 * next input to be decoded is dec_buffer + input_chunk.
1467 */
1468 PyObject *next_input = PyNumber_Add(dec_buffer, input_chunk);
1469 if (next_input == NULL)
1470 goto fail;
Serhiy Storchaka354d50e2013-02-03 17:10:42 +02001471 if (!PyBytes_Check(next_input)) {
1472 PyErr_Format(PyExc_TypeError,
1473 "decoder getstate() should have returned a bytes "
1474 "object, not '%.200s'",
1475 Py_TYPE(next_input)->tp_name);
1476 Py_DECREF(next_input);
1477 goto fail;
1478 }
Antoine Pitrou19690592009-06-12 20:14:08 +00001479 Py_DECREF(dec_buffer);
1480 Py_CLEAR(self->snapshot);
1481 self->snapshot = Py_BuildValue("NN", dec_flags, next_input);
1482 }
1483 Py_DECREF(input_chunk);
1484
1485 return (eof == 0);
1486
1487 fail:
1488 Py_XDECREF(dec_buffer);
1489 Py_XDECREF(dec_flags);
1490 Py_XDECREF(input_chunk);
1491 return -1;
1492}
1493
1494static PyObject *
1495textiowrapper_read(textio *self, PyObject *args)
1496{
1497 Py_ssize_t n = -1;
1498 PyObject *result = NULL, *chunks = NULL;
1499
Benjamin Peterson53ae6142014-12-21 20:51:50 -06001500 CHECK_ATTACHED(self);
Antoine Pitrou19690592009-06-12 20:14:08 +00001501
Benjamin Petersonddd392c2009-12-13 19:19:07 +00001502 if (!PyArg_ParseTuple(args, "|O&:read", &_PyIO_ConvertSsize_t, &n))
Antoine Pitrou19690592009-06-12 20:14:08 +00001503 return NULL;
1504
1505 CHECK_CLOSED(self);
1506
1507 if (self->decoder == NULL) {
1508 PyErr_SetString(PyExc_IOError, "not readable");
1509 return NULL;
1510 }
1511
1512 if (_textiowrapper_writeflush(self) < 0)
1513 return NULL;
1514
1515 if (n < 0) {
1516 /* Read everything */
1517 PyObject *bytes = PyObject_CallMethod(self->buffer, "read", NULL);
1518 PyObject *decoded, *final;
1519 if (bytes == NULL)
1520 goto fail;
1521 decoded = PyObject_CallMethodObjArgs(self->decoder, _PyIO_str_decode,
1522 bytes, Py_True, NULL);
1523 Py_DECREF(bytes);
Serhiy Storchaka354d50e2013-02-03 17:10:42 +02001524 if (check_decoded(decoded) < 0)
Antoine Pitrou19690592009-06-12 20:14:08 +00001525 goto fail;
1526
1527 result = textiowrapper_get_decoded_chars(self, -1);
1528
1529 if (result == NULL) {
1530 Py_DECREF(decoded);
1531 return NULL;
1532 }
1533
1534 final = PyUnicode_Concat(result, decoded);
1535 Py_DECREF(result);
1536 Py_DECREF(decoded);
1537 if (final == NULL)
1538 goto fail;
1539
1540 Py_CLEAR(self->snapshot);
1541 return final;
1542 }
1543 else {
1544 int res = 1;
1545 Py_ssize_t remaining = n;
1546
1547 result = textiowrapper_get_decoded_chars(self, n);
1548 if (result == NULL)
1549 goto fail;
1550 remaining -= PyUnicode_GET_SIZE(result);
1551
1552 /* Keep reading chunks until we have n characters to return */
1553 while (remaining > 0) {
1554 res = textiowrapper_read_chunk(self);
Gregory P. Smith99716162012-10-12 13:02:06 -07001555 if (res < 0) {
1556 /* NOTE: PyErr_SetFromErrno() calls PyErr_CheckSignals()
1557 when EINTR occurs so we needn't do it ourselves. */
1558 if (_PyIO_trap_eintr()) {
1559 continue;
1560 }
Antoine Pitrou19690592009-06-12 20:14:08 +00001561 goto fail;
Gregory P. Smith99716162012-10-12 13:02:06 -07001562 }
Antoine Pitrou19690592009-06-12 20:14:08 +00001563 if (res == 0) /* EOF */
1564 break;
1565 if (chunks == NULL) {
1566 chunks = PyList_New(0);
1567 if (chunks == NULL)
1568 goto fail;
1569 }
1570 if (PyList_Append(chunks, result) < 0)
1571 goto fail;
1572 Py_DECREF(result);
1573 result = textiowrapper_get_decoded_chars(self, remaining);
1574 if (result == NULL)
1575 goto fail;
1576 remaining -= PyUnicode_GET_SIZE(result);
1577 }
1578 if (chunks != NULL) {
1579 if (result != NULL && PyList_Append(chunks, result) < 0)
1580 goto fail;
1581 Py_CLEAR(result);
1582 result = PyUnicode_Join(_PyIO_empty_str, chunks);
1583 if (result == NULL)
1584 goto fail;
1585 Py_CLEAR(chunks);
1586 }
1587 return result;
1588 }
1589 fail:
1590 Py_XDECREF(result);
1591 Py_XDECREF(chunks);
1592 return NULL;
1593}
1594
1595
1596/* NOTE: `end` must point to the real end of the Py_UNICODE storage,
1597 that is to the NUL character. Otherwise the function will produce
1598 incorrect results. */
1599static Py_UNICODE *
1600find_control_char(Py_UNICODE *start, Py_UNICODE *end, Py_UNICODE ch)
1601{
1602 Py_UNICODE *s = start;
1603 for (;;) {
1604 while (*s > ch)
1605 s++;
1606 if (*s == ch)
1607 return s;
1608 if (s == end)
1609 return NULL;
1610 s++;
1611 }
1612}
1613
1614Py_ssize_t
1615_PyIO_find_line_ending(
1616 int translated, int universal, PyObject *readnl,
1617 Py_UNICODE *start, Py_UNICODE *end, Py_ssize_t *consumed)
1618{
1619 Py_ssize_t len = end - start;
1620
1621 if (translated) {
1622 /* Newlines are already translated, only search for \n */
1623 Py_UNICODE *pos = find_control_char(start, end, '\n');
1624 if (pos != NULL)
1625 return pos - start + 1;
1626 else {
1627 *consumed = len;
1628 return -1;
1629 }
1630 }
1631 else if (universal) {
1632 /* Universal newline search. Find any of \r, \r\n, \n
1633 * The decoder ensures that \r\n are not split in two pieces
1634 */
1635 Py_UNICODE *s = start;
1636 for (;;) {
1637 Py_UNICODE ch;
1638 /* Fast path for non-control chars. The loop always ends
1639 since the Py_UNICODE storage is NUL-terminated. */
1640 while (*s > '\r')
1641 s++;
1642 if (s >= end) {
1643 *consumed = len;
1644 return -1;
1645 }
1646 ch = *s++;
1647 if (ch == '\n')
1648 return s - start;
1649 if (ch == '\r') {
1650 if (*s == '\n')
1651 return s - start + 1;
1652 else
1653 return s - start;
1654 }
1655 }
1656 }
1657 else {
1658 /* Non-universal mode. */
1659 Py_ssize_t readnl_len = PyString_GET_SIZE(readnl);
1660 unsigned char *nl = (unsigned char *) PyString_AS_STRING(readnl);
1661 if (readnl_len == 1) {
1662 Py_UNICODE *pos = find_control_char(start, end, nl[0]);
1663 if (pos != NULL)
1664 return pos - start + 1;
1665 *consumed = len;
1666 return -1;
1667 }
1668 else {
1669 Py_UNICODE *s = start;
1670 Py_UNICODE *e = end - readnl_len + 1;
1671 Py_UNICODE *pos;
1672 if (e < s)
1673 e = s;
1674 while (s < e) {
1675 Py_ssize_t i;
1676 Py_UNICODE *pos = find_control_char(s, end, nl[0]);
1677 if (pos == NULL || pos >= e)
1678 break;
1679 for (i = 1; i < readnl_len; i++) {
1680 if (pos[i] != nl[i])
1681 break;
1682 }
1683 if (i == readnl_len)
1684 return pos - start + readnl_len;
1685 s = pos + 1;
1686 }
1687 pos = find_control_char(e, end, nl[0]);
1688 if (pos == NULL)
1689 *consumed = len;
1690 else
1691 *consumed = pos - start;
1692 return -1;
1693 }
1694 }
1695}
1696
1697static PyObject *
1698_textiowrapper_readline(textio *self, Py_ssize_t limit)
1699{
1700 PyObject *line = NULL, *chunks = NULL, *remaining = NULL;
1701 Py_ssize_t start, endpos, chunked, offset_to_buffer;
1702 int res;
1703
1704 CHECK_CLOSED(self);
1705
1706 if (_textiowrapper_writeflush(self) < 0)
1707 return NULL;
1708
1709 chunked = 0;
1710
1711 while (1) {
1712 Py_UNICODE *ptr;
1713 Py_ssize_t line_len;
1714 Py_ssize_t consumed = 0;
1715
1716 /* First, get some data if necessary */
1717 res = 1;
1718 while (!self->decoded_chars ||
1719 !PyUnicode_GET_SIZE(self->decoded_chars)) {
1720 res = textiowrapper_read_chunk(self);
Gregory P. Smith99716162012-10-12 13:02:06 -07001721 if (res < 0) {
1722 /* NOTE: PyErr_SetFromErrno() calls PyErr_CheckSignals()
1723 when EINTR occurs so we needn't do it ourselves. */
1724 if (_PyIO_trap_eintr()) {
1725 continue;
1726 }
Antoine Pitrou19690592009-06-12 20:14:08 +00001727 goto error;
Gregory P. Smith99716162012-10-12 13:02:06 -07001728 }
Antoine Pitrou19690592009-06-12 20:14:08 +00001729 if (res == 0)
1730 break;
1731 }
1732 if (res == 0) {
1733 /* end of file */
1734 textiowrapper_set_decoded_chars(self, NULL);
1735 Py_CLEAR(self->snapshot);
1736 start = endpos = offset_to_buffer = 0;
1737 break;
1738 }
1739
1740 if (remaining == NULL) {
1741 line = self->decoded_chars;
1742 start = self->decoded_chars_used;
1743 offset_to_buffer = 0;
1744 Py_INCREF(line);
1745 }
1746 else {
1747 assert(self->decoded_chars_used == 0);
1748 line = PyUnicode_Concat(remaining, self->decoded_chars);
1749 start = 0;
1750 offset_to_buffer = PyUnicode_GET_SIZE(remaining);
1751 Py_CLEAR(remaining);
1752 if (line == NULL)
1753 goto error;
1754 }
1755
1756 ptr = PyUnicode_AS_UNICODE(line);
1757 line_len = PyUnicode_GET_SIZE(line);
1758
1759 endpos = _PyIO_find_line_ending(
1760 self->readtranslate, self->readuniversal, self->readnl,
1761 ptr + start, ptr + line_len, &consumed);
1762 if (endpos >= 0) {
1763 endpos += start;
1764 if (limit >= 0 && (endpos - start) + chunked >= limit)
1765 endpos = start + limit - chunked;
1766 break;
1767 }
1768
1769 /* We can put aside up to `endpos` */
1770 endpos = consumed + start;
1771 if (limit >= 0 && (endpos - start) + chunked >= limit) {
1772 /* Didn't find line ending, but reached length limit */
1773 endpos = start + limit - chunked;
1774 break;
1775 }
1776
1777 if (endpos > start) {
1778 /* No line ending seen yet - put aside current data */
1779 PyObject *s;
1780 if (chunks == NULL) {
1781 chunks = PyList_New(0);
1782 if (chunks == NULL)
1783 goto error;
1784 }
1785 s = PyUnicode_FromUnicode(ptr + start, endpos - start);
1786 if (s == NULL)
1787 goto error;
1788 if (PyList_Append(chunks, s) < 0) {
1789 Py_DECREF(s);
1790 goto error;
1791 }
1792 chunked += PyUnicode_GET_SIZE(s);
1793 Py_DECREF(s);
1794 }
1795 /* There may be some remaining bytes we'll have to prepend to the
1796 next chunk of data */
1797 if (endpos < line_len) {
1798 remaining = PyUnicode_FromUnicode(
1799 ptr + endpos, line_len - endpos);
1800 if (remaining == NULL)
1801 goto error;
1802 }
1803 Py_CLEAR(line);
1804 /* We have consumed the buffer */
1805 textiowrapper_set_decoded_chars(self, NULL);
1806 }
1807
1808 if (line != NULL) {
1809 /* Our line ends in the current buffer */
1810 self->decoded_chars_used = endpos - offset_to_buffer;
1811 if (start > 0 || endpos < PyUnicode_GET_SIZE(line)) {
1812 if (start == 0 && Py_REFCNT(line) == 1) {
1813 if (PyUnicode_Resize(&line, endpos) < 0)
1814 goto error;
1815 }
1816 else {
1817 PyObject *s = PyUnicode_FromUnicode(
1818 PyUnicode_AS_UNICODE(line) + start, endpos - start);
1819 Py_CLEAR(line);
1820 if (s == NULL)
1821 goto error;
1822 line = s;
1823 }
1824 }
1825 }
1826 if (remaining != NULL) {
1827 if (chunks == NULL) {
1828 chunks = PyList_New(0);
1829 if (chunks == NULL)
1830 goto error;
1831 }
1832 if (PyList_Append(chunks, remaining) < 0)
1833 goto error;
1834 Py_CLEAR(remaining);
1835 }
1836 if (chunks != NULL) {
1837 if (line != NULL && PyList_Append(chunks, line) < 0)
1838 goto error;
1839 Py_CLEAR(line);
1840 line = PyUnicode_Join(_PyIO_empty_str, chunks);
1841 if (line == NULL)
1842 goto error;
1843 Py_DECREF(chunks);
1844 }
1845 if (line == NULL)
1846 line = PyUnicode_FromStringAndSize(NULL, 0);
1847
1848 return line;
1849
1850 error:
1851 Py_XDECREF(chunks);
1852 Py_XDECREF(remaining);
1853 Py_XDECREF(line);
1854 return NULL;
1855}
1856
1857static PyObject *
1858textiowrapper_readline(textio *self, PyObject *args)
1859{
1860 PyObject *limitobj = NULL;
1861 Py_ssize_t limit = -1;
1862
Benjamin Peterson53ae6142014-12-21 20:51:50 -06001863 CHECK_ATTACHED(self);
Antoine Pitrou19690592009-06-12 20:14:08 +00001864 if (!PyArg_ParseTuple(args, "|O:readline", &limitobj)) {
1865 return NULL;
1866 }
1867 if (limitobj) {
1868 if (!PyNumber_Check(limitobj)) {
1869 PyErr_Format(PyExc_TypeError,
1870 "integer argument expected, got '%.200s'",
1871 Py_TYPE(limitobj)->tp_name);
1872 return NULL;
1873 }
1874 limit = PyNumber_AsSsize_t(limitobj, PyExc_OverflowError);
1875 if (limit == -1 && PyErr_Occurred())
1876 return NULL;
1877 }
1878 return _textiowrapper_readline(self, limit);
1879}
1880
1881/* Seek and Tell */
1882
1883typedef struct {
1884 Py_off_t start_pos;
1885 int dec_flags;
1886 int bytes_to_feed;
1887 int chars_to_skip;
1888 char need_eof;
1889} cookie_type;
1890
1891/*
1892 To speed up cookie packing/unpacking, we store the fields in a temporary
1893 string and call _PyLong_FromByteArray() or _PyLong_AsByteArray (resp.).
1894 The following macros define at which offsets in the intermediary byte
1895 string the various CookieStruct fields will be stored.
1896 */
1897
1898#define COOKIE_BUF_LEN (sizeof(Py_off_t) + 3 * sizeof(int) + sizeof(char))
1899
1900#if defined(WORDS_BIGENDIAN)
1901
1902# define IS_LITTLE_ENDIAN 0
1903
1904/* We want the least significant byte of start_pos to also be the least
1905 significant byte of the cookie, which means that in big-endian mode we
1906 must copy the fields in reverse order. */
1907
1908# define OFF_START_POS (sizeof(char) + 3 * sizeof(int))
1909# define OFF_DEC_FLAGS (sizeof(char) + 2 * sizeof(int))
1910# define OFF_BYTES_TO_FEED (sizeof(char) + sizeof(int))
1911# define OFF_CHARS_TO_SKIP (sizeof(char))
1912# define OFF_NEED_EOF 0
1913
1914#else
1915
1916# define IS_LITTLE_ENDIAN 1
1917
1918/* Little-endian mode: the least significant byte of start_pos will
1919 naturally end up the least significant byte of the cookie. */
1920
1921# define OFF_START_POS 0
1922# define OFF_DEC_FLAGS (sizeof(Py_off_t))
1923# define OFF_BYTES_TO_FEED (sizeof(Py_off_t) + sizeof(int))
1924# define OFF_CHARS_TO_SKIP (sizeof(Py_off_t) + 2 * sizeof(int))
1925# define OFF_NEED_EOF (sizeof(Py_off_t) + 3 * sizeof(int))
1926
1927#endif
1928
1929static int
1930textiowrapper_parse_cookie(cookie_type *cookie, PyObject *cookieObj)
1931{
1932 unsigned char buffer[COOKIE_BUF_LEN];
1933 PyLongObject *cookieLong = (PyLongObject *)PyNumber_Long(cookieObj);
1934 if (cookieLong == NULL)
1935 return -1;
1936
1937 if (_PyLong_AsByteArray(cookieLong, buffer, sizeof(buffer),
1938 IS_LITTLE_ENDIAN, 0) < 0) {
1939 Py_DECREF(cookieLong);
1940 return -1;
1941 }
1942 Py_DECREF(cookieLong);
1943
1944 memcpy(&cookie->start_pos, buffer + OFF_START_POS, sizeof(cookie->start_pos));
1945 memcpy(&cookie->dec_flags, buffer + OFF_DEC_FLAGS, sizeof(cookie->dec_flags));
1946 memcpy(&cookie->bytes_to_feed, buffer + OFF_BYTES_TO_FEED, sizeof(cookie->bytes_to_feed));
1947 memcpy(&cookie->chars_to_skip, buffer + OFF_CHARS_TO_SKIP, sizeof(cookie->chars_to_skip));
1948 memcpy(&cookie->need_eof, buffer + OFF_NEED_EOF, sizeof(cookie->need_eof));
1949
1950 return 0;
1951}
1952
1953static PyObject *
1954textiowrapper_build_cookie(cookie_type *cookie)
1955{
1956 unsigned char buffer[COOKIE_BUF_LEN];
1957
1958 memcpy(buffer + OFF_START_POS, &cookie->start_pos, sizeof(cookie->start_pos));
1959 memcpy(buffer + OFF_DEC_FLAGS, &cookie->dec_flags, sizeof(cookie->dec_flags));
1960 memcpy(buffer + OFF_BYTES_TO_FEED, &cookie->bytes_to_feed, sizeof(cookie->bytes_to_feed));
1961 memcpy(buffer + OFF_CHARS_TO_SKIP, &cookie->chars_to_skip, sizeof(cookie->chars_to_skip));
1962 memcpy(buffer + OFF_NEED_EOF, &cookie->need_eof, sizeof(cookie->need_eof));
1963
1964 return _PyLong_FromByteArray(buffer, sizeof(buffer), IS_LITTLE_ENDIAN, 0);
1965}
1966#undef IS_LITTLE_ENDIAN
1967
1968static int
1969_textiowrapper_decoder_setstate(textio *self, cookie_type *cookie)
1970{
1971 PyObject *res;
1972 /* When seeking to the start of the stream, we call decoder.reset()
1973 rather than decoder.getstate().
1974 This is for a few decoders such as utf-16 for which the state value
1975 at start is not (b"", 0) but e.g. (b"", 2) (meaning, in the case of
1976 utf-16, that we are expecting a BOM).
1977 */
1978 if (cookie->start_pos == 0 && cookie->dec_flags == 0)
1979 res = PyObject_CallMethodObjArgs(self->decoder, _PyIO_str_reset, NULL);
1980 else
1981 res = PyObject_CallMethod(self->decoder, "setstate",
1982 "((si))", "", cookie->dec_flags);
1983 if (res == NULL)
1984 return -1;
1985 Py_DECREF(res);
1986 return 0;
1987}
1988
1989static int
1990_textiowrapper_encoder_setstate(textio *self, cookie_type *cookie)
1991{
1992 PyObject *res;
1993 /* Same as _textiowrapper_decoder_setstate() above. */
1994 if (cookie->start_pos == 0 && cookie->dec_flags == 0) {
1995 res = PyObject_CallMethodObjArgs(self->encoder, _PyIO_str_reset, NULL);
1996 self->encoding_start_of_stream = 1;
1997 }
1998 else {
1999 res = PyObject_CallMethodObjArgs(self->encoder, _PyIO_str_setstate,
2000 _PyIO_zero, NULL);
2001 self->encoding_start_of_stream = 0;
2002 }
2003 if (res == NULL)
2004 return -1;
2005 Py_DECREF(res);
2006 return 0;
2007}
2008
2009static PyObject *
2010textiowrapper_seek(textio *self, PyObject *args)
2011{
2012 PyObject *cookieObj, *posobj;
2013 cookie_type cookie;
2014 int whence = 0;
2015 PyObject *res;
2016 int cmp;
2017
Benjamin Peterson53ae6142014-12-21 20:51:50 -06002018 CHECK_ATTACHED(self);
Antoine Pitrou19690592009-06-12 20:14:08 +00002019
2020 if (!PyArg_ParseTuple(args, "O|i:seek", &cookieObj, &whence))
2021 return NULL;
2022 CHECK_CLOSED(self);
2023
2024 Py_INCREF(cookieObj);
2025
2026 if (!self->seekable) {
2027 PyErr_SetString(PyExc_IOError,
2028 "underlying stream is not seekable");
2029 goto fail;
2030 }
2031
2032 if (whence == 1) {
2033 /* seek relative to current position */
2034 cmp = PyObject_RichCompareBool(cookieObj, _PyIO_zero, Py_EQ);
2035 if (cmp < 0)
2036 goto fail;
2037
2038 if (cmp == 0) {
2039 PyErr_SetString(PyExc_IOError,
2040 "can't do nonzero cur-relative seeks");
2041 goto fail;
2042 }
2043
2044 /* Seeking to the current position should attempt to
2045 * sync the underlying buffer with the current position.
2046 */
2047 Py_DECREF(cookieObj);
2048 cookieObj = PyObject_CallMethod((PyObject *)self, "tell", NULL);
2049 if (cookieObj == NULL)
2050 goto fail;
2051 }
2052 else if (whence == 2) {
2053 /* seek relative to end of file */
2054
2055 cmp = PyObject_RichCompareBool(cookieObj, _PyIO_zero, Py_EQ);
2056 if (cmp < 0)
2057 goto fail;
2058
2059 if (cmp == 0) {
2060 PyErr_SetString(PyExc_IOError,
2061 "can't do nonzero end-relative seeks");
2062 goto fail;
2063 }
2064
2065 res = PyObject_CallMethod((PyObject *)self, "flush", NULL);
2066 if (res == NULL)
2067 goto fail;
2068 Py_DECREF(res);
2069
2070 textiowrapper_set_decoded_chars(self, NULL);
2071 Py_CLEAR(self->snapshot);
2072 if (self->decoder) {
2073 res = PyObject_CallMethod(self->decoder, "reset", NULL);
2074 if (res == NULL)
2075 goto fail;
2076 Py_DECREF(res);
2077 }
2078
2079 res = PyObject_CallMethod(self->buffer, "seek", "ii", 0, 2);
2080 Py_XDECREF(cookieObj);
2081 return res;
2082 }
2083 else if (whence != 0) {
2084 PyErr_Format(PyExc_ValueError,
2085 "invalid whence (%d, should be 0, 1 or 2)", whence);
2086 goto fail;
2087 }
2088
2089 cmp = PyObject_RichCompareBool(cookieObj, _PyIO_zero, Py_LT);
2090 if (cmp < 0)
2091 goto fail;
2092
2093 if (cmp == 1) {
2094 PyObject *repr = PyObject_Repr(cookieObj);
2095 if (repr != NULL) {
2096 PyErr_Format(PyExc_ValueError,
2097 "negative seek position %s",
2098 PyString_AS_STRING(repr));
2099 Py_DECREF(repr);
2100 }
2101 goto fail;
2102 }
2103
2104 res = PyObject_CallMethodObjArgs((PyObject *)self, _PyIO_str_flush, NULL);
2105 if (res == NULL)
2106 goto fail;
2107 Py_DECREF(res);
2108
2109 /* The strategy of seek() is to go back to the safe start point
2110 * and replay the effect of read(chars_to_skip) from there.
2111 */
2112 if (textiowrapper_parse_cookie(&cookie, cookieObj) < 0)
2113 goto fail;
2114
2115 /* Seek back to the safe start point. */
2116 posobj = PyLong_FromOff_t(cookie.start_pos);
2117 if (posobj == NULL)
2118 goto fail;
2119 res = PyObject_CallMethodObjArgs(self->buffer,
2120 _PyIO_str_seek, posobj, NULL);
2121 Py_DECREF(posobj);
2122 if (res == NULL)
2123 goto fail;
2124 Py_DECREF(res);
2125
2126 textiowrapper_set_decoded_chars(self, NULL);
2127 Py_CLEAR(self->snapshot);
2128
2129 /* Restore the decoder to its state from the safe start point. */
2130 if (self->decoder) {
2131 if (_textiowrapper_decoder_setstate(self, &cookie) < 0)
2132 goto fail;
2133 }
2134
2135 if (cookie.chars_to_skip) {
2136 /* Just like _read_chunk, feed the decoder and save a snapshot. */
2137 PyObject *input_chunk = PyObject_CallMethod(
2138 self->buffer, "read", "i", cookie.bytes_to_feed);
2139 PyObject *decoded;
2140
2141 if (input_chunk == NULL)
2142 goto fail;
2143
Serhiy Storchaka354d50e2013-02-03 17:10:42 +02002144 if (!PyBytes_Check(input_chunk)) {
2145 PyErr_Format(PyExc_TypeError,
2146 "underlying read() should have returned a bytes "
2147 "object, not '%.200s'",
2148 Py_TYPE(input_chunk)->tp_name);
2149 Py_DECREF(input_chunk);
2150 goto fail;
2151 }
Antoine Pitrou19690592009-06-12 20:14:08 +00002152
2153 self->snapshot = Py_BuildValue("iN", cookie.dec_flags, input_chunk);
2154 if (self->snapshot == NULL) {
2155 Py_DECREF(input_chunk);
2156 goto fail;
2157 }
2158
2159 decoded = PyObject_CallMethod(self->decoder, "decode",
2160 "Oi", input_chunk, (int)cookie.need_eof);
2161
Serhiy Storchaka354d50e2013-02-03 17:10:42 +02002162 if (check_decoded(decoded) < 0)
Antoine Pitrou19690592009-06-12 20:14:08 +00002163 goto fail;
2164
2165 textiowrapper_set_decoded_chars(self, decoded);
2166
2167 /* Skip chars_to_skip of the decoded characters. */
2168 if (PyUnicode_GetSize(self->decoded_chars) < cookie.chars_to_skip) {
2169 PyErr_SetString(PyExc_IOError, "can't restore logical file position");
2170 goto fail;
2171 }
2172 self->decoded_chars_used = cookie.chars_to_skip;
2173 }
2174 else {
2175 self->snapshot = Py_BuildValue("is", cookie.dec_flags, "");
2176 if (self->snapshot == NULL)
2177 goto fail;
2178 }
2179
2180 /* Finally, reset the encoder (merely useful for proper BOM handling) */
2181 if (self->encoder) {
2182 if (_textiowrapper_encoder_setstate(self, &cookie) < 0)
2183 goto fail;
2184 }
2185 return cookieObj;
2186 fail:
2187 Py_XDECREF(cookieObj);
2188 return NULL;
2189
2190}
2191
2192static PyObject *
2193textiowrapper_tell(textio *self, PyObject *args)
2194{
2195 PyObject *res;
2196 PyObject *posobj = NULL;
2197 cookie_type cookie = {0,0,0,0,0};
2198 PyObject *next_input;
2199 Py_ssize_t chars_to_skip, chars_decoded;
2200 PyObject *saved_state = NULL;
2201 char *input, *input_end;
2202
Benjamin Peterson53ae6142014-12-21 20:51:50 -06002203 CHECK_ATTACHED(self);
Antoine Pitrou19690592009-06-12 20:14:08 +00002204 CHECK_CLOSED(self);
2205
2206 if (!self->seekable) {
2207 PyErr_SetString(PyExc_IOError,
2208 "underlying stream is not seekable");
2209 goto fail;
2210 }
2211 if (!self->telling) {
2212 PyErr_SetString(PyExc_IOError,
2213 "telling position disabled by next() call");
2214 goto fail;
2215 }
2216
2217 if (_textiowrapper_writeflush(self) < 0)
2218 return NULL;
2219 res = PyObject_CallMethod((PyObject *)self, "flush", NULL);
2220 if (res == NULL)
2221 goto fail;
2222 Py_DECREF(res);
2223
2224 posobj = PyObject_CallMethod(self->buffer, "tell", NULL);
2225 if (posobj == NULL)
2226 goto fail;
2227
2228 if (self->decoder == NULL || self->snapshot == NULL) {
2229 assert (self->decoded_chars == NULL || PyUnicode_GetSize(self->decoded_chars) == 0);
2230 return posobj;
2231 }
2232
2233#if defined(HAVE_LARGEFILE_SUPPORT)
2234 cookie.start_pos = PyLong_AsLongLong(posobj);
2235#else
2236 cookie.start_pos = PyLong_AsLong(posobj);
2237#endif
2238 if (PyErr_Occurred())
2239 goto fail;
2240
2241 /* Skip backward to the snapshot point (see _read_chunk). */
2242 if (!PyArg_Parse(self->snapshot, "(iO)", &cookie.dec_flags, &next_input))
2243 goto fail;
2244
2245 assert (PyBytes_Check(next_input));
2246
2247 cookie.start_pos -= PyBytes_GET_SIZE(next_input);
2248
2249 /* How many decoded characters have been used up since the snapshot? */
2250 if (self->decoded_chars_used == 0) {
2251 /* We haven't moved from the snapshot point. */
2252 Py_DECREF(posobj);
2253 return textiowrapper_build_cookie(&cookie);
2254 }
2255
2256 chars_to_skip = self->decoded_chars_used;
2257
2258 /* Starting from the snapshot position, we will walk the decoder
2259 * forward until it gives us enough decoded characters.
2260 */
2261 saved_state = PyObject_CallMethodObjArgs(self->decoder,
2262 _PyIO_str_getstate, NULL);
2263 if (saved_state == NULL)
2264 goto fail;
2265
2266 /* Note our initial start point. */
2267 if (_textiowrapper_decoder_setstate(self, &cookie) < 0)
2268 goto fail;
2269
2270 /* Feed the decoder one byte at a time. As we go, note the
2271 * nearest "safe start point" before the current location
2272 * (a point where the decoder has nothing buffered, so seek()
2273 * can safely start from there and advance to this location).
2274 */
2275 chars_decoded = 0;
2276 input = PyBytes_AS_STRING(next_input);
2277 input_end = input + PyBytes_GET_SIZE(next_input);
2278 while (input < input_end) {
2279 PyObject *state;
2280 char *dec_buffer;
2281 Py_ssize_t dec_buffer_len;
2282 int dec_flags;
2283
2284 PyObject *decoded = PyObject_CallMethod(
Serhiy Storchakaa9885e92013-08-20 20:08:53 +03002285 self->decoder, "decode", "s#", input, (Py_ssize_t)1);
Serhiy Storchaka354d50e2013-02-03 17:10:42 +02002286 if (check_decoded(decoded) < 0)
Antoine Pitrou19690592009-06-12 20:14:08 +00002287 goto fail;
Antoine Pitrou19690592009-06-12 20:14:08 +00002288 chars_decoded += PyUnicode_GET_SIZE(decoded);
2289 Py_DECREF(decoded);
2290
2291 cookie.bytes_to_feed += 1;
2292
2293 state = PyObject_CallMethodObjArgs(self->decoder,
2294 _PyIO_str_getstate, NULL);
2295 if (state == NULL)
2296 goto fail;
2297 if (!PyArg_Parse(state, "(s#i)", &dec_buffer, &dec_buffer_len, &dec_flags)) {
2298 Py_DECREF(state);
2299 goto fail;
2300 }
2301 Py_DECREF(state);
2302
2303 if (dec_buffer_len == 0 && chars_decoded <= chars_to_skip) {
2304 /* Decoder buffer is empty, so this is a safe start point. */
2305 cookie.start_pos += cookie.bytes_to_feed;
2306 chars_to_skip -= chars_decoded;
2307 cookie.dec_flags = dec_flags;
2308 cookie.bytes_to_feed = 0;
2309 chars_decoded = 0;
2310 }
2311 if (chars_decoded >= chars_to_skip)
2312 break;
2313 input++;
2314 }
2315 if (input == input_end) {
2316 /* We didn't get enough decoded data; signal EOF to get more. */
2317 PyObject *decoded = PyObject_CallMethod(
2318 self->decoder, "decode", "si", "", /* final = */ 1);
Serhiy Storchaka354d50e2013-02-03 17:10:42 +02002319 if (check_decoded(decoded) < 0)
Antoine Pitrou19690592009-06-12 20:14:08 +00002320 goto fail;
Antoine Pitrou19690592009-06-12 20:14:08 +00002321 chars_decoded += PyUnicode_GET_SIZE(decoded);
2322 Py_DECREF(decoded);
2323 cookie.need_eof = 1;
2324
2325 if (chars_decoded < chars_to_skip) {
2326 PyErr_SetString(PyExc_IOError,
2327 "can't reconstruct logical file position");
2328 goto fail;
2329 }
2330 }
2331
2332 /* finally */
2333 Py_XDECREF(posobj);
2334 res = PyObject_CallMethod(self->decoder, "setstate", "(O)", saved_state);
2335 Py_DECREF(saved_state);
2336 if (res == NULL)
2337 return NULL;
2338 Py_DECREF(res);
2339
2340 /* The returned cookie corresponds to the last safe start point. */
2341 cookie.chars_to_skip = Py_SAFE_DOWNCAST(chars_to_skip, Py_ssize_t, int);
2342 return textiowrapper_build_cookie(&cookie);
2343
2344 fail:
2345 Py_XDECREF(posobj);
2346 if (saved_state) {
2347 PyObject *type, *value, *traceback;
2348 PyErr_Fetch(&type, &value, &traceback);
2349
2350 res = PyObject_CallMethod(self->decoder, "setstate", "(O)", saved_state);
Serhiy Storchaka96d80122015-03-30 10:00:49 +03002351 _PyErr_ReplaceException(type, value, traceback);
Antoine Pitrou19690592009-06-12 20:14:08 +00002352 Py_DECREF(saved_state);
Serhiy Storchaka96d80122015-03-30 10:00:49 +03002353 Py_XDECREF(res);
Antoine Pitrou19690592009-06-12 20:14:08 +00002354 }
2355 return NULL;
2356}
2357
2358static PyObject *
2359textiowrapper_truncate(textio *self, PyObject *args)
2360{
2361 PyObject *pos = Py_None;
2362 PyObject *res;
2363
Benjamin Peterson53ae6142014-12-21 20:51:50 -06002364 CHECK_ATTACHED(self)
Antoine Pitrou19690592009-06-12 20:14:08 +00002365 if (!PyArg_ParseTuple(args, "|O:truncate", &pos)) {
2366 return NULL;
2367 }
2368
2369 res = PyObject_CallMethodObjArgs((PyObject *) self, _PyIO_str_flush, NULL);
2370 if (res == NULL)
2371 return NULL;
2372 Py_DECREF(res);
2373
Antoine Pitrouf3fa0742010-01-31 22:26:04 +00002374 return PyObject_CallMethodObjArgs(self->buffer, _PyIO_str_truncate, pos, NULL);
Antoine Pitrou19690592009-06-12 20:14:08 +00002375}
2376
2377static PyObject *
2378textiowrapper_repr(textio *self)
2379{
2380 PyObject *nameobj, *res;
2381 PyObject *namerepr = NULL, *encrepr = NULL;
2382
2383 CHECK_INITIALIZED(self);
2384
2385 nameobj = PyObject_GetAttrString((PyObject *) self, "name");
2386 if (nameobj == NULL) {
Benjamin Peterson53ae6142014-12-21 20:51:50 -06002387 if (PyErr_ExceptionMatches(PyExc_Exception))
Antoine Pitrou19690592009-06-12 20:14:08 +00002388 PyErr_Clear();
2389 else
2390 goto error;
2391 encrepr = PyObject_Repr(self->encoding);
2392 res = PyString_FromFormat("<_io.TextIOWrapper encoding=%s>",
2393 PyString_AS_STRING(encrepr));
2394 }
2395 else {
2396 encrepr = PyObject_Repr(self->encoding);
2397 namerepr = PyObject_Repr(nameobj);
2398 res = PyString_FromFormat("<_io.TextIOWrapper name=%s encoding=%s>",
2399 PyString_AS_STRING(namerepr),
2400 PyString_AS_STRING(encrepr));
2401 Py_DECREF(nameobj);
2402 }
2403 Py_XDECREF(namerepr);
2404 Py_XDECREF(encrepr);
2405 return res;
2406
2407error:
2408 Py_XDECREF(namerepr);
2409 Py_XDECREF(encrepr);
2410 return NULL;
2411}
2412
2413
2414/* Inquiries */
2415
2416static PyObject *
2417textiowrapper_fileno(textio *self, PyObject *args)
2418{
Benjamin Peterson53ae6142014-12-21 20:51:50 -06002419 CHECK_ATTACHED(self);
Antoine Pitrou19690592009-06-12 20:14:08 +00002420 return PyObject_CallMethod(self->buffer, "fileno", NULL);
2421}
2422
2423static PyObject *
2424textiowrapper_seekable(textio *self, PyObject *args)
2425{
Benjamin Peterson53ae6142014-12-21 20:51:50 -06002426 CHECK_ATTACHED(self);
Antoine Pitrou19690592009-06-12 20:14:08 +00002427 return PyObject_CallMethod(self->buffer, "seekable", NULL);
2428}
2429
2430static PyObject *
2431textiowrapper_readable(textio *self, PyObject *args)
2432{
Benjamin Peterson53ae6142014-12-21 20:51:50 -06002433 CHECK_ATTACHED(self);
Antoine Pitrou19690592009-06-12 20:14:08 +00002434 return PyObject_CallMethod(self->buffer, "readable", NULL);
2435}
2436
2437static PyObject *
2438textiowrapper_writable(textio *self, PyObject *args)
2439{
Benjamin Peterson53ae6142014-12-21 20:51:50 -06002440 CHECK_ATTACHED(self);
Antoine Pitrou19690592009-06-12 20:14:08 +00002441 return PyObject_CallMethod(self->buffer, "writable", NULL);
2442}
2443
2444static PyObject *
2445textiowrapper_isatty(textio *self, PyObject *args)
2446{
Benjamin Peterson53ae6142014-12-21 20:51:50 -06002447 CHECK_ATTACHED(self);
Antoine Pitrou19690592009-06-12 20:14:08 +00002448 return PyObject_CallMethod(self->buffer, "isatty", NULL);
2449}
2450
2451static PyObject *
2452textiowrapper_flush(textio *self, PyObject *args)
2453{
Benjamin Peterson53ae6142014-12-21 20:51:50 -06002454 CHECK_ATTACHED(self);
Antoine Pitrou19690592009-06-12 20:14:08 +00002455 CHECK_CLOSED(self);
2456 self->telling = self->seekable;
2457 if (_textiowrapper_writeflush(self) < 0)
2458 return NULL;
2459 return PyObject_CallMethod(self->buffer, "flush", NULL);
2460}
2461
2462static PyObject *
2463textiowrapper_close(textio *self, PyObject *args)
2464{
2465 PyObject *res;
Antoine Pitrouf7fd8e42010-05-03 16:25:33 +00002466 int r;
Benjamin Peterson53ae6142014-12-21 20:51:50 -06002467 CHECK_ATTACHED(self);
Antoine Pitrou19690592009-06-12 20:14:08 +00002468
Antoine Pitrouf7fd8e42010-05-03 16:25:33 +00002469 res = textiowrapper_closed_get(self, NULL);
2470 if (res == NULL)
2471 return NULL;
2472 r = PyObject_IsTrue(res);
2473 Py_DECREF(res);
2474 if (r < 0)
2475 return NULL;
Serhiy Storchaka354d50e2013-02-03 17:10:42 +02002476
Antoine Pitrouf7fd8e42010-05-03 16:25:33 +00002477 if (r > 0) {
2478 Py_RETURN_NONE; /* stream already closed */
2479 }
2480 else {
Benjamin Petersona2d6d712012-12-20 12:24:10 -06002481 PyObject *exc = NULL, *val, *tb;
Antoine Pitrouf7fd8e42010-05-03 16:25:33 +00002482 res = PyObject_CallMethod((PyObject *)self, "flush", NULL);
Benjamin Petersona2d6d712012-12-20 12:24:10 -06002483 if (res == NULL)
2484 PyErr_Fetch(&exc, &val, &tb);
Antoine Pitrouf7fd8e42010-05-03 16:25:33 +00002485 else
2486 Py_DECREF(res);
2487
Benjamin Petersona2d6d712012-12-20 12:24:10 -06002488 res = PyObject_CallMethod(self->buffer, "close", NULL);
2489 if (exc != NULL) {
Serhiy Storchakaaa64c462015-03-30 09:48:42 +03002490 _PyErr_ReplaceException(exc, val, tb);
2491 Py_CLEAR(res);
Benjamin Petersona2d6d712012-12-20 12:24:10 -06002492 }
2493 return res;
Antoine Pitrouf7fd8e42010-05-03 16:25:33 +00002494 }
Antoine Pitrou19690592009-06-12 20:14:08 +00002495}
2496
2497static PyObject *
2498textiowrapper_iternext(textio *self)
2499{
2500 PyObject *line;
2501
Benjamin Peterson53ae6142014-12-21 20:51:50 -06002502 CHECK_ATTACHED(self);
Antoine Pitrou19690592009-06-12 20:14:08 +00002503
2504 self->telling = 0;
2505 if (Py_TYPE(self) == &PyTextIOWrapper_Type) {
2506 /* Skip method call overhead for speed */
2507 line = _textiowrapper_readline(self, -1);
2508 }
2509 else {
2510 line = PyObject_CallMethodObjArgs((PyObject *)self,
2511 _PyIO_str_readline, NULL);
2512 if (line && !PyUnicode_Check(line)) {
2513 PyErr_Format(PyExc_IOError,
2514 "readline() should have returned an str object, "
2515 "not '%.200s'", Py_TYPE(line)->tp_name);
2516 Py_DECREF(line);
2517 return NULL;
2518 }
2519 }
2520
2521 if (line == NULL)
2522 return NULL;
2523
2524 if (PyUnicode_GET_SIZE(line) == 0) {
2525 /* Reached EOF or would have blocked */
2526 Py_DECREF(line);
2527 Py_CLEAR(self->snapshot);
2528 self->telling = self->seekable;
2529 return NULL;
2530 }
2531
2532 return line;
2533}
2534
2535static PyObject *
2536textiowrapper_name_get(textio *self, void *context)
2537{
Benjamin Peterson53ae6142014-12-21 20:51:50 -06002538 CHECK_ATTACHED(self);
Antoine Pitrou19690592009-06-12 20:14:08 +00002539 return PyObject_GetAttrString(self->buffer, "name");
2540}
2541
2542static PyObject *
2543textiowrapper_closed_get(textio *self, void *context)
2544{
Benjamin Peterson53ae6142014-12-21 20:51:50 -06002545 CHECK_ATTACHED(self);
Antoine Pitrou19690592009-06-12 20:14:08 +00002546 return PyObject_GetAttr(self->buffer, _PyIO_str_closed);
2547}
2548
2549static PyObject *
2550textiowrapper_newlines_get(textio *self, void *context)
2551{
2552 PyObject *res;
Benjamin Peterson53ae6142014-12-21 20:51:50 -06002553 CHECK_ATTACHED(self);
Antoine Pitrou19690592009-06-12 20:14:08 +00002554 if (self->decoder == NULL)
2555 Py_RETURN_NONE;
2556 res = PyObject_GetAttr(self->decoder, _PyIO_str_newlines);
2557 if (res == NULL) {
2558 if (PyErr_ExceptionMatches(PyExc_AttributeError)) {
2559 PyErr_Clear();
2560 Py_RETURN_NONE;
2561 }
2562 else {
2563 return NULL;
2564 }
2565 }
2566 return res;
2567}
2568
2569static PyObject *
2570textiowrapper_errors_get(textio *self, void *context)
2571{
2572 CHECK_INITIALIZED(self);
2573 Py_INCREF(self->errors);
2574 return self->errors;
2575}
2576
2577static PyObject *
2578textiowrapper_chunk_size_get(textio *self, void *context)
2579{
Benjamin Peterson53ae6142014-12-21 20:51:50 -06002580 CHECK_ATTACHED(self);
Antoine Pitrou19690592009-06-12 20:14:08 +00002581 return PyLong_FromSsize_t(self->chunk_size);
2582}
2583
2584static int
2585textiowrapper_chunk_size_set(textio *self, PyObject *arg, void *context)
2586{
2587 Py_ssize_t n;
Benjamin Peterson53ae6142014-12-21 20:51:50 -06002588 CHECK_ATTACHED_INT(self);
Antoine Pitrou19690592009-06-12 20:14:08 +00002589 n = PyNumber_AsSsize_t(arg, PyExc_TypeError);
2590 if (n == -1 && PyErr_Occurred())
2591 return -1;
2592 if (n <= 0) {
2593 PyErr_SetString(PyExc_ValueError,
2594 "a strictly positive integer is required");
2595 return -1;
2596 }
2597 self->chunk_size = n;
2598 return 0;
2599}
2600
2601static PyMethodDef textiowrapper_methods[] = {
2602 {"detach", (PyCFunction)textiowrapper_detach, METH_NOARGS},
2603 {"write", (PyCFunction)textiowrapper_write, METH_VARARGS},
2604 {"read", (PyCFunction)textiowrapper_read, METH_VARARGS},
2605 {"readline", (PyCFunction)textiowrapper_readline, METH_VARARGS},
2606 {"flush", (PyCFunction)textiowrapper_flush, METH_NOARGS},
2607 {"close", (PyCFunction)textiowrapper_close, METH_NOARGS},
2608
2609 {"fileno", (PyCFunction)textiowrapper_fileno, METH_NOARGS},
2610 {"seekable", (PyCFunction)textiowrapper_seekable, METH_NOARGS},
2611 {"readable", (PyCFunction)textiowrapper_readable, METH_NOARGS},
2612 {"writable", (PyCFunction)textiowrapper_writable, METH_NOARGS},
2613 {"isatty", (PyCFunction)textiowrapper_isatty, METH_NOARGS},
2614
2615 {"seek", (PyCFunction)textiowrapper_seek, METH_VARARGS},
2616 {"tell", (PyCFunction)textiowrapper_tell, METH_NOARGS},
2617 {"truncate", (PyCFunction)textiowrapper_truncate, METH_VARARGS},
2618 {NULL, NULL}
2619};
2620
2621static PyMemberDef textiowrapper_members[] = {
2622 {"encoding", T_OBJECT, offsetof(textio, encoding), READONLY},
2623 {"buffer", T_OBJECT, offsetof(textio, buffer), READONLY},
2624 {"line_buffering", T_BOOL, offsetof(textio, line_buffering), READONLY},
2625 {NULL}
2626};
2627
2628static PyGetSetDef textiowrapper_getset[] = {
2629 {"name", (getter)textiowrapper_name_get, NULL, NULL},
2630 {"closed", (getter)textiowrapper_closed_get, NULL, NULL},
2631/* {"mode", (getter)TextIOWrapper_mode_get, NULL, NULL},
2632*/
2633 {"newlines", (getter)textiowrapper_newlines_get, NULL, NULL},
2634 {"errors", (getter)textiowrapper_errors_get, NULL, NULL},
2635 {"_CHUNK_SIZE", (getter)textiowrapper_chunk_size_get,
2636 (setter)textiowrapper_chunk_size_set, NULL},
2637 {NULL}
2638};
2639
2640PyTypeObject PyTextIOWrapper_Type = {
2641 PyVarObject_HEAD_INIT(NULL, 0)
2642 "_io.TextIOWrapper", /*tp_name*/
2643 sizeof(textio), /*tp_basicsize*/
2644 0, /*tp_itemsize*/
2645 (destructor)textiowrapper_dealloc, /*tp_dealloc*/
2646 0, /*tp_print*/
2647 0, /*tp_getattr*/
2648 0, /*tps_etattr*/
2649 0, /*tp_compare */
2650 (reprfunc)textiowrapper_repr,/*tp_repr*/
2651 0, /*tp_as_number*/
2652 0, /*tp_as_sequence*/
2653 0, /*tp_as_mapping*/
2654 0, /*tp_hash */
2655 0, /*tp_call*/
2656 0, /*tp_str*/
2657 0, /*tp_getattro*/
2658 0, /*tp_setattro*/
2659 0, /*tp_as_buffer*/
2660 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE
2661 | Py_TPFLAGS_HAVE_GC, /*tp_flags*/
2662 textiowrapper_doc, /* tp_doc */
2663 (traverseproc)textiowrapper_traverse, /* tp_traverse */
2664 (inquiry)textiowrapper_clear, /* tp_clear */
2665 0, /* tp_richcompare */
2666 offsetof(textio, weakreflist), /*tp_weaklistoffset*/
2667 0, /* tp_iter */
2668 (iternextfunc)textiowrapper_iternext, /* tp_iternext */
2669 textiowrapper_methods, /* tp_methods */
2670 textiowrapper_members, /* tp_members */
2671 textiowrapper_getset, /* tp_getset */
2672 0, /* tp_base */
2673 0, /* tp_dict */
2674 0, /* tp_descr_get */
2675 0, /* tp_descr_set */
2676 offsetof(textio, dict), /*tp_dictoffset*/
2677 (initproc)textiowrapper_init, /* tp_init */
2678 0, /* tp_alloc */
2679 PyType_GenericNew, /* tp_new */
2680};