blob: 9b7334d3b54a52941d554a78505959a626078aba [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
Serhiy Storchakaf24131f2015-04-16 11:19:43 +030014/*[clinic input]
15module _io
16class _io.IncrementalNewlineDecoder "nldecoder_object *" "&PyIncrementalNewlineDecoder_Type"
17class _io.TextIOWrapper "textio *" "&TextIOWrapper_TYpe"
18[clinic start generated code]*/
19/*[clinic end generated code: output=da39a3ee5e6b4b0d input=2097a4fc85670c26]*/
20
Martin v. Löwisbd928fe2011-10-14 10:20:37 +020021_Py_IDENTIFIER(close);
22_Py_IDENTIFIER(_dealloc_warn);
23_Py_IDENTIFIER(decode);
Martin v. Löwisbd928fe2011-10-14 10:20:37 +020024_Py_IDENTIFIER(fileno);
25_Py_IDENTIFIER(flush);
26_Py_IDENTIFIER(getpreferredencoding);
27_Py_IDENTIFIER(isatty);
Martin v. Löwis767046a2011-10-14 15:35:36 +020028_Py_IDENTIFIER(mode);
29_Py_IDENTIFIER(name);
30_Py_IDENTIFIER(raw);
Martin v. Löwisbd928fe2011-10-14 10:20:37 +020031_Py_IDENTIFIER(read);
Martin v. Löwis767046a2011-10-14 15:35:36 +020032_Py_IDENTIFIER(read1);
Martin v. Löwisbd928fe2011-10-14 10:20:37 +020033_Py_IDENTIFIER(readable);
34_Py_IDENTIFIER(replace);
35_Py_IDENTIFIER(reset);
36_Py_IDENTIFIER(seek);
37_Py_IDENTIFIER(seekable);
38_Py_IDENTIFIER(setstate);
39_Py_IDENTIFIER(tell);
40_Py_IDENTIFIER(writable);
Martin v. Löwisafe55bb2011-10-09 10:38:36 +020041
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +000042/* TextIOBase */
43
Benjamin Peterson680bf1a2009-06-12 02:07:12 +000044PyDoc_STRVAR(textiobase_doc,
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +000045 "Base class for text I/O.\n"
46 "\n"
47 "This class provides a character and line based interface to stream\n"
48 "I/O. There is no readinto method because Python's character strings\n"
49 "are immutable. There is no public constructor.\n"
50 );
51
52static PyObject *
53_unsupported(const char *message)
54{
Antoine Pitrou712cb732013-12-21 15:51:54 +010055 _PyIO_State *state = IO_STATE();
56 if (state != NULL)
57 PyErr_SetString(state->unsupported_operation, message);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +000058 return NULL;
59}
60
Benjamin Peterson680bf1a2009-06-12 02:07:12 +000061PyDoc_STRVAR(textiobase_detach_doc,
Benjamin Petersond2e0c792009-05-01 20:40:59 +000062 "Separate the underlying buffer from the TextIOBase and return it.\n"
63 "\n"
64 "After the underlying buffer has been detached, the TextIO is in an\n"
65 "unusable state.\n"
66 );
67
68static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +000069textiobase_detach(PyObject *self)
Benjamin Petersond2e0c792009-05-01 20:40:59 +000070{
71 return _unsupported("detach");
72}
73
Benjamin Peterson680bf1a2009-06-12 02:07:12 +000074PyDoc_STRVAR(textiobase_read_doc,
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +000075 "Read at most n characters from stream.\n"
76 "\n"
77 "Read from underlying buffer until we have n characters or we hit EOF.\n"
78 "If n is negative or omitted, read until EOF.\n"
79 );
80
81static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +000082textiobase_read(PyObject *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +000083{
84 return _unsupported("read");
85}
86
Benjamin Peterson680bf1a2009-06-12 02:07:12 +000087PyDoc_STRVAR(textiobase_readline_doc,
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +000088 "Read until newline or EOF.\n"
89 "\n"
90 "Returns an empty string if EOF is hit immediately.\n"
91 );
92
93static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +000094textiobase_readline(PyObject *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +000095{
96 return _unsupported("readline");
97}
98
Benjamin Peterson680bf1a2009-06-12 02:07:12 +000099PyDoc_STRVAR(textiobase_write_doc,
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000100 "Write string to stream.\n"
101 "Returns the number of characters written (which is always equal to\n"
102 "the length of the string).\n"
103 );
104
105static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000106textiobase_write(PyObject *self, PyObject *args)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000107{
108 return _unsupported("write");
109}
110
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000111PyDoc_STRVAR(textiobase_encoding_doc,
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000112 "Encoding of the text stream.\n"
113 "\n"
114 "Subclasses should override.\n"
115 );
116
117static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000118textiobase_encoding_get(PyObject *self, void *context)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000119{
120 Py_RETURN_NONE;
121}
122
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000123PyDoc_STRVAR(textiobase_newlines_doc,
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000124 "Line endings translated so far.\n"
125 "\n"
126 "Only line endings translated during reading are considered.\n"
127 "\n"
128 "Subclasses should override.\n"
129 );
130
131static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000132textiobase_newlines_get(PyObject *self, void *context)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000133{
134 Py_RETURN_NONE;
135}
136
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000137PyDoc_STRVAR(textiobase_errors_doc,
Benjamin Peterson0926ad12009-06-06 18:02:12 +0000138 "The error setting of the decoder or encoder.\n"
139 "\n"
140 "Subclasses should override.\n"
141 );
142
143static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000144textiobase_errors_get(PyObject *self, void *context)
Benjamin Peterson0926ad12009-06-06 18:02:12 +0000145{
146 Py_RETURN_NONE;
147}
148
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000149
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000150static PyMethodDef textiobase_methods[] = {
151 {"detach", (PyCFunction)textiobase_detach, METH_NOARGS, textiobase_detach_doc},
152 {"read", textiobase_read, METH_VARARGS, textiobase_read_doc},
153 {"readline", textiobase_readline, METH_VARARGS, textiobase_readline_doc},
154 {"write", textiobase_write, METH_VARARGS, textiobase_write_doc},
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000155 {NULL, NULL}
156};
157
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000158static PyGetSetDef textiobase_getset[] = {
159 {"encoding", (getter)textiobase_encoding_get, NULL, textiobase_encoding_doc},
160 {"newlines", (getter)textiobase_newlines_get, NULL, textiobase_newlines_doc},
161 {"errors", (getter)textiobase_errors_get, NULL, textiobase_errors_doc},
Benjamin Peterson1fea3212009-04-19 03:15:20 +0000162 {NULL}
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000163};
164
165PyTypeObject PyTextIOBase_Type = {
166 PyVarObject_HEAD_INIT(NULL, 0)
167 "_io._TextIOBase", /*tp_name*/
168 0, /*tp_basicsize*/
169 0, /*tp_itemsize*/
170 0, /*tp_dealloc*/
171 0, /*tp_print*/
172 0, /*tp_getattr*/
173 0, /*tp_setattr*/
174 0, /*tp_compare */
175 0, /*tp_repr*/
176 0, /*tp_as_number*/
177 0, /*tp_as_sequence*/
178 0, /*tp_as_mapping*/
179 0, /*tp_hash */
180 0, /*tp_call*/
181 0, /*tp_str*/
182 0, /*tp_getattro*/
183 0, /*tp_setattro*/
184 0, /*tp_as_buffer*/
Antoine Pitrou796564c2013-07-30 19:59:21 +0200185 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE
186 | Py_TPFLAGS_HAVE_FINALIZE, /*tp_flags*/
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000187 textiobase_doc, /* tp_doc */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000188 0, /* tp_traverse */
189 0, /* tp_clear */
190 0, /* tp_richcompare */
191 0, /* tp_weaklistoffset */
192 0, /* tp_iter */
193 0, /* tp_iternext */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000194 textiobase_methods, /* tp_methods */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000195 0, /* tp_members */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000196 textiobase_getset, /* tp_getset */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000197 &PyIOBase_Type, /* tp_base */
198 0, /* tp_dict */
199 0, /* tp_descr_get */
200 0, /* tp_descr_set */
201 0, /* tp_dictoffset */
202 0, /* tp_init */
203 0, /* tp_alloc */
204 0, /* tp_new */
Antoine Pitrou796564c2013-07-30 19:59:21 +0200205 0, /* tp_free */
206 0, /* tp_is_gc */
207 0, /* tp_bases */
208 0, /* tp_mro */
209 0, /* tp_cache */
210 0, /* tp_subclasses */
211 0, /* tp_weaklist */
212 0, /* tp_del */
213 0, /* tp_version_tag */
214 0, /* tp_finalize */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000215};
216
217
218/* IncrementalNewlineDecoder */
219
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000220typedef struct {
221 PyObject_HEAD
222 PyObject *decoder;
223 PyObject *errors;
Victor Stinner7d7e7752014-06-17 23:31:25 +0200224 unsigned int pendingcr: 1;
225 unsigned int translate: 1;
Antoine Pitrouca767bd2009-09-21 21:37:02 +0000226 unsigned int seennl: 3;
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000227} nldecoder_object;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000228
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300229/*[clinic input]
230_io.IncrementalNewlineDecoder.__init__
231 decoder: object
232 translate: int
233 errors: object(c_default="NULL") = "strict"
234
235Codec used when reading a file in universal newlines mode.
236
237It wraps another incremental decoder, translating \r\n and \r into \n.
238It also records the types of newlines encountered. When used with
239translate=False, it ensures that the newline sequence is returned in
240one piece. When used with decoder=None, it expects unicode strings as
241decode input and translates newlines without first invoking an external
242decoder.
243[clinic start generated code]*/
244
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000245static int
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300246_io_IncrementalNewlineDecoder___init___impl(nldecoder_object *self,
247 PyObject *decoder, int translate,
248 PyObject *errors)
249/*[clinic end generated code: output=fbd04d443e764ec2 input=89db6b19c6b126bf]*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000250{
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000251 self->decoder = decoder;
252 Py_INCREF(decoder);
253
254 if (errors == NULL) {
255 self->errors = PyUnicode_FromString("strict");
256 if (self->errors == NULL)
257 return -1;
258 }
259 else {
260 Py_INCREF(errors);
261 self->errors = errors;
262 }
263
264 self->translate = translate;
265 self->seennl = 0;
266 self->pendingcr = 0;
267
268 return 0;
269}
270
271static void
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000272incrementalnewlinedecoder_dealloc(nldecoder_object *self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000273{
274 Py_CLEAR(self->decoder);
275 Py_CLEAR(self->errors);
276 Py_TYPE(self)->tp_free((PyObject *)self);
277}
278
Serhiy Storchaka94dc6732013-02-03 17:03:31 +0200279static int
280check_decoded(PyObject *decoded)
281{
282 if (decoded == NULL)
283 return -1;
284 if (!PyUnicode_Check(decoded)) {
285 PyErr_Format(PyExc_TypeError,
286 "decoder should return a string result, not '%.200s'",
287 Py_TYPE(decoded)->tp_name);
288 Py_DECREF(decoded);
289 return -1;
290 }
Serhiy Storchakad03ce4a2013-02-03 17:07:32 +0200291 if (PyUnicode_READY(decoded) < 0) {
292 Py_DECREF(decoded);
293 return -1;
294 }
Serhiy Storchaka94dc6732013-02-03 17:03:31 +0200295 return 0;
296}
297
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000298#define SEEN_CR 1
299#define SEEN_LF 2
300#define SEEN_CRLF 4
301#define SEEN_ALL (SEEN_CR | SEEN_LF | SEEN_CRLF)
302
303PyObject *
Antoine Pitrou09fcb722013-10-23 19:20:21 +0200304_PyIncrementalNewlineDecoder_decode(PyObject *myself,
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000305 PyObject *input, int final)
306{
307 PyObject *output;
308 Py_ssize_t output_len;
Antoine Pitrou09fcb722013-10-23 19:20:21 +0200309 nldecoder_object *self = (nldecoder_object *) myself;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000310
311 if (self->decoder == NULL) {
312 PyErr_SetString(PyExc_ValueError,
313 "IncrementalNewlineDecoder.__init__ not called");
314 return NULL;
315 }
316
317 /* decode input (with the eventual \r from a previous pass) */
318 if (self->decoder != Py_None) {
319 output = PyObject_CallMethodObjArgs(self->decoder,
320 _PyIO_str_decode, input, final ? Py_True : Py_False, NULL);
321 }
322 else {
323 output = input;
324 Py_INCREF(output);
325 }
326
Serhiy Storchaka94dc6732013-02-03 17:03:31 +0200327 if (check_decoded(output) < 0)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000328 return NULL;
329
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200330 output_len = PyUnicode_GET_LENGTH(output);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000331 if (self->pendingcr && (final || output_len > 0)) {
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200332 /* Prefix output with CR */
333 int kind;
334 PyObject *modified;
335 char *out;
336
337 modified = PyUnicode_New(output_len + 1,
338 PyUnicode_MAX_CHAR_VALUE(output));
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000339 if (modified == NULL)
340 goto error;
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200341 kind = PyUnicode_KIND(modified);
342 out = PyUnicode_DATA(modified);
343 PyUnicode_WRITE(kind, PyUnicode_DATA(modified), 0, '\r');
Martin v. Löwisc47adb02011-10-07 20:55:35 +0200344 memcpy(out + kind, PyUnicode_DATA(output), kind * output_len);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000345 Py_DECREF(output);
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200346 output = modified; /* output remains ready */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000347 self->pendingcr = 0;
348 output_len++;
349 }
350
351 /* retain last \r even when not translating data:
352 * then readline() is sure to get \r\n in one pass
353 */
354 if (!final) {
Antoine Pitrou24f36292009-03-28 22:16:42 +0000355 if (output_len > 0
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200356 && PyUnicode_READ_CHAR(output, output_len - 1) == '\r')
357 {
358 PyObject *modified = PyUnicode_Substring(output, 0, output_len -1);
359 if (modified == NULL)
360 goto error;
361 Py_DECREF(output);
362 output = modified;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000363 self->pendingcr = 1;
364 }
365 }
366
367 /* Record which newlines are read and do newline translation if desired,
368 all in one pass. */
369 {
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200370 void *in_str;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000371 Py_ssize_t len;
372 int seennl = self->seennl;
373 int only_lf = 0;
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200374 int kind;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000375
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200376 in_str = PyUnicode_DATA(output);
377 len = PyUnicode_GET_LENGTH(output);
378 kind = PyUnicode_KIND(output);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000379
380 if (len == 0)
381 return output;
382
383 /* If, up to now, newlines are consistently \n, do a quick check
384 for the \r *byte* with the libc's optimized memchr.
385 */
386 if (seennl == SEEN_LF || seennl == 0) {
Martin v. Löwisc47adb02011-10-07 20:55:35 +0200387 only_lf = (memchr(in_str, '\r', kind * len) == NULL);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000388 }
389
Antoine Pitrou66913e22009-03-06 23:40:56 +0000390 if (only_lf) {
391 /* If not already seen, quick scan for a possible "\n" character.
392 (there's nothing else to be done, even when in translation mode)
393 */
394 if (seennl == 0 &&
Martin v. Löwisc47adb02011-10-07 20:55:35 +0200395 memchr(in_str, '\n', kind * len) != NULL) {
Antoine Pitrouc28e2e52011-11-13 03:53:42 +0100396 if (kind == PyUnicode_1BYTE_KIND)
397 seennl |= SEEN_LF;
398 else {
399 Py_ssize_t i = 0;
400 for (;;) {
401 Py_UCS4 c;
402 /* Fast loop for non-control characters */
403 while (PyUnicode_READ(kind, in_str, i) > '\n')
404 i++;
405 c = PyUnicode_READ(kind, in_str, i++);
406 if (c == '\n') {
407 seennl |= SEEN_LF;
408 break;
409 }
410 if (i >= len)
411 break;
Antoine Pitrou66913e22009-03-06 23:40:56 +0000412 }
Antoine Pitrou66913e22009-03-06 23:40:56 +0000413 }
414 }
415 /* Finished: we have scanned for newlines, and none of them
416 need translating */
417 }
418 else if (!self->translate) {
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200419 Py_ssize_t i = 0;
Antoine Pitrou66913e22009-03-06 23:40:56 +0000420 /* We have already seen all newline types, no need to scan again */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000421 if (seennl == SEEN_ALL)
422 goto endscan;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000423 for (;;) {
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200424 Py_UCS4 c;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000425 /* Fast loop for non-control characters */
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200426 while (PyUnicode_READ(kind, in_str, i) > '\r')
427 i++;
428 c = PyUnicode_READ(kind, in_str, i++);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000429 if (c == '\n')
430 seennl |= SEEN_LF;
431 else if (c == '\r') {
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200432 if (PyUnicode_READ(kind, in_str, i) == '\n') {
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000433 seennl |= SEEN_CRLF;
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200434 i++;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000435 }
436 else
437 seennl |= SEEN_CR;
438 }
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200439 if (i >= len)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000440 break;
441 if (seennl == SEEN_ALL)
442 break;
443 }
444 endscan:
445 ;
446 }
Antoine Pitrou66913e22009-03-06 23:40:56 +0000447 else {
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200448 void *translated;
449 int kind = PyUnicode_KIND(output);
450 void *in_str = PyUnicode_DATA(output);
451 Py_ssize_t in, out;
452 /* XXX: Previous in-place translation here is disabled as
453 resizing is not possible anymore */
454 /* We could try to optimize this so that we only do a copy
455 when there is something to translate. On the other hand,
456 we already know there is a \r byte, so chances are high
457 that something needs to be done. */
Martin v. Löwisc47adb02011-10-07 20:55:35 +0200458 translated = PyMem_Malloc(kind * len);
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200459 if (translated == NULL) {
460 PyErr_NoMemory();
461 goto error;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000462 }
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200463 in = out = 0;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000464 for (;;) {
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200465 Py_UCS4 c;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000466 /* Fast loop for non-control characters */
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200467 while ((c = PyUnicode_READ(kind, in_str, in++)) > '\r')
468 PyUnicode_WRITE(kind, translated, out++, c);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000469 if (c == '\n') {
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200470 PyUnicode_WRITE(kind, translated, out++, c);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000471 seennl |= SEEN_LF;
472 continue;
473 }
474 if (c == '\r') {
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200475 if (PyUnicode_READ(kind, in_str, in) == '\n') {
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000476 in++;
477 seennl |= SEEN_CRLF;
478 }
479 else
480 seennl |= SEEN_CR;
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200481 PyUnicode_WRITE(kind, translated, out++, '\n');
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000482 continue;
483 }
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200484 if (in > len)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000485 break;
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200486 PyUnicode_WRITE(kind, translated, out++, c);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000487 }
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200488 Py_DECREF(output);
489 output = PyUnicode_FromKindAndData(kind, translated, out);
Antoine Pitrouc1b0bfd2011-11-12 22:34:28 +0100490 PyMem_Free(translated);
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200491 if (!output)
Ross Lagerwall0f9eec12012-04-07 07:09:57 +0200492 return NULL;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000493 }
494 self->seennl |= seennl;
495 }
496
497 return output;
498
499 error:
500 Py_DECREF(output);
501 return NULL;
502}
503
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300504/*[clinic input]
505_io.IncrementalNewlineDecoder.decode
506 input: object
Serhiy Storchaka202fda52017-03-12 10:10:47 +0200507 final: bool(accept={int}) = False
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300508[clinic start generated code]*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000509
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300510static PyObject *
511_io_IncrementalNewlineDecoder_decode_impl(nldecoder_object *self,
512 PyObject *input, int final)
Serhiy Storchaka202fda52017-03-12 10:10:47 +0200513/*[clinic end generated code: output=0d486755bb37a66e input=a4ea97f26372d866]*/
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300514{
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000515 return _PyIncrementalNewlineDecoder_decode((PyObject *) self, input, final);
516}
517
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300518/*[clinic input]
519_io.IncrementalNewlineDecoder.getstate
520[clinic start generated code]*/
521
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000522static PyObject *
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300523_io_IncrementalNewlineDecoder_getstate_impl(nldecoder_object *self)
524/*[clinic end generated code: output=f0d2c9c136f4e0d0 input=f8ff101825e32e7f]*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000525{
526 PyObject *buffer;
Benjamin Peterson47ff0732016-09-08 09:15:54 -0700527 unsigned long long flag;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000528
529 if (self->decoder != Py_None) {
530 PyObject *state = PyObject_CallMethodObjArgs(self->decoder,
531 _PyIO_str_getstate, NULL);
532 if (state == NULL)
533 return NULL;
Oren Milman13614e32017-08-24 19:51:24 +0300534 if (!PyTuple_Check(state)) {
535 PyErr_SetString(PyExc_TypeError,
536 "illegal decoder state");
537 Py_DECREF(state);
538 return NULL;
539 }
540 if (!PyArg_ParseTuple(state, "OK;illegal decoder state",
541 &buffer, &flag))
542 {
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000543 Py_DECREF(state);
544 return NULL;
545 }
546 Py_INCREF(buffer);
547 Py_DECREF(state);
548 }
549 else {
550 buffer = PyBytes_FromString("");
551 flag = 0;
552 }
553 flag <<= 1;
554 if (self->pendingcr)
555 flag |= 1;
556 return Py_BuildValue("NK", buffer, flag);
557}
558
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300559/*[clinic input]
560_io.IncrementalNewlineDecoder.setstate
561 state: object
562 /
563[clinic start generated code]*/
564
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000565static PyObject *
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300566_io_IncrementalNewlineDecoder_setstate(nldecoder_object *self,
567 PyObject *state)
568/*[clinic end generated code: output=c10c622508b576cb input=c53fb505a76dbbe2]*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000569{
570 PyObject *buffer;
Benjamin Peterson47ff0732016-09-08 09:15:54 -0700571 unsigned long long flag;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000572
Oren Milman1d1d3e92017-08-20 18:35:36 +0300573 if (!PyTuple_Check(state)) {
574 PyErr_SetString(PyExc_TypeError, "state argument must be a tuple");
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000575 return NULL;
Oren Milman1d1d3e92017-08-20 18:35:36 +0300576 }
577 if (!PyArg_ParseTuple(state, "OK;setstate(): illegal state argument",
578 &buffer, &flag))
579 {
580 return NULL;
581 }
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000582
Victor Stinner7d7e7752014-06-17 23:31:25 +0200583 self->pendingcr = (int) (flag & 1);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000584 flag >>= 1;
585
586 if (self->decoder != Py_None)
Martin v. Löwisafe55bb2011-10-09 10:38:36 +0200587 return _PyObject_CallMethodId(self->decoder,
588 &PyId_setstate, "((OK))", buffer, flag);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000589 else
590 Py_RETURN_NONE;
591}
592
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300593/*[clinic input]
594_io.IncrementalNewlineDecoder.reset
595[clinic start generated code]*/
596
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000597static PyObject *
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300598_io_IncrementalNewlineDecoder_reset_impl(nldecoder_object *self)
599/*[clinic end generated code: output=32fa40c7462aa8ff input=728678ddaea776df]*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000600{
601 self->seennl = 0;
602 self->pendingcr = 0;
603 if (self->decoder != Py_None)
604 return PyObject_CallMethodObjArgs(self->decoder, _PyIO_str_reset, NULL);
605 else
606 Py_RETURN_NONE;
607}
608
609static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000610incrementalnewlinedecoder_newlines_get(nldecoder_object *self, void *context)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000611{
612 switch (self->seennl) {
613 case SEEN_CR:
614 return PyUnicode_FromString("\r");
615 case SEEN_LF:
616 return PyUnicode_FromString("\n");
617 case SEEN_CRLF:
618 return PyUnicode_FromString("\r\n");
619 case SEEN_CR | SEEN_LF:
620 return Py_BuildValue("ss", "\r", "\n");
621 case SEEN_CR | SEEN_CRLF:
622 return Py_BuildValue("ss", "\r", "\r\n");
623 case SEEN_LF | SEEN_CRLF:
624 return Py_BuildValue("ss", "\n", "\r\n");
625 case SEEN_CR | SEEN_LF | SEEN_CRLF:
626 return Py_BuildValue("sss", "\r", "\n", "\r\n");
627 default:
628 Py_RETURN_NONE;
629 }
630
631}
632
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000633/* TextIOWrapper */
634
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000635typedef PyObject *
636 (*encodefunc_t)(PyObject *, PyObject *);
637
638typedef struct
639{
640 PyObject_HEAD
641 int ok; /* initialized? */
Benjamin Petersond2e0c792009-05-01 20:40:59 +0000642 int detached;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000643 Py_ssize_t chunk_size;
644 PyObject *buffer;
645 PyObject *encoding;
646 PyObject *encoder;
647 PyObject *decoder;
648 PyObject *readnl;
649 PyObject *errors;
650 const char *writenl; /* utf-8 encoded, NULL stands for \n */
651 char line_buffering;
Antoine Pitroue96ec682011-07-23 21:46:35 +0200652 char write_through;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000653 char readuniversal;
654 char readtranslate;
655 char writetranslate;
656 char seekable;
Antoine Pitroue96ec682011-07-23 21:46:35 +0200657 char has_read1;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000658 char telling;
Antoine Pitrou796564c2013-07-30 19:59:21 +0200659 char finalizing;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000660 /* Specialized encoding func (see below) */
661 encodefunc_t encodefunc;
Antoine Pitroue4501852009-05-14 18:55:55 +0000662 /* Whether or not it's the start of the stream */
663 char encoding_start_of_stream;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000664
665 /* Reads and writes are internally buffered in order to speed things up.
666 However, any read will first flush the write buffer if itsn't empty.
Antoine Pitrou24f36292009-03-28 22:16:42 +0000667
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000668 Please also note that text to be written is first encoded before being
669 buffered. This is necessary so that encoding errors are immediately
670 reported to the caller, but it unfortunately means that the
671 IncrementalEncoder (whose encode() method is always written in Python)
672 becomes a bottleneck for small writes.
673 */
674 PyObject *decoded_chars; /* buffer for text returned from decoder */
675 Py_ssize_t decoded_chars_used; /* offset into _decoded_chars for read() */
676 PyObject *pending_bytes; /* list of bytes objects waiting to be
677 written, or NULL */
678 Py_ssize_t pending_bytes_count;
Antoine Pitrou211b81d2011-02-25 20:27:33 +0000679
Oren Milman13614e32017-08-24 19:51:24 +0300680 /* snapshot is either NULL, or a tuple (dec_flags, next_input) where
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000681 * dec_flags is the second (integer) item of the decoder state and
682 * next_input is the chunk of input bytes that comes next after the
683 * snapshot point. We use this to reconstruct decoder states in tell().
684 */
Antoine Pitrou211b81d2011-02-25 20:27:33 +0000685 PyObject *snapshot;
686 /* Bytes-to-characters ratio for the current chunk. Serves as input for
687 the heuristic in tell(). */
688 double b2cratio;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000689
690 /* Cache raw object if it's a FileIO object */
691 PyObject *raw;
692
693 PyObject *weakreflist;
694 PyObject *dict;
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000695} textio;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000696
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000697/* A couple of specialized cases in order to bypass the slow incremental
698 encoding methods for the most popular encodings. */
699
700static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000701ascii_encode(textio *self, PyObject *text)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000702{
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200703 return _PyUnicode_AsASCIIString(text, PyBytes_AS_STRING(self->errors));
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000704}
705
706static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000707utf16be_encode(textio *self, PyObject *text)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000708{
Antoine Pitrou5c398e82011-11-13 04:11:37 +0100709 return _PyUnicode_EncodeUTF16(text,
710 PyBytes_AS_STRING(self->errors), 1);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000711}
712
713static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000714utf16le_encode(textio *self, PyObject *text)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000715{
Antoine Pitrou5c398e82011-11-13 04:11:37 +0100716 return _PyUnicode_EncodeUTF16(text,
717 PyBytes_AS_STRING(self->errors), -1);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000718}
719
720static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000721utf16_encode(textio *self, PyObject *text)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000722{
Antoine Pitroue4501852009-05-14 18:55:55 +0000723 if (!self->encoding_start_of_stream) {
724 /* Skip the BOM and use native byte ordering */
Christian Heimes743e0cd2012-10-17 23:52:17 +0200725#if PY_BIG_ENDIAN
Antoine Pitroue4501852009-05-14 18:55:55 +0000726 return utf16be_encode(self, text);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000727#else
Antoine Pitroue4501852009-05-14 18:55:55 +0000728 return utf16le_encode(self, text);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000729#endif
Antoine Pitroue4501852009-05-14 18:55:55 +0000730 }
Antoine Pitrou5c398e82011-11-13 04:11:37 +0100731 return _PyUnicode_EncodeUTF16(text,
732 PyBytes_AS_STRING(self->errors), 0);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000733}
734
Antoine Pitroue4501852009-05-14 18:55:55 +0000735static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000736utf32be_encode(textio *self, PyObject *text)
Antoine Pitroue4501852009-05-14 18:55:55 +0000737{
Antoine Pitrou5c398e82011-11-13 04:11:37 +0100738 return _PyUnicode_EncodeUTF32(text,
739 PyBytes_AS_STRING(self->errors), 1);
Antoine Pitroue4501852009-05-14 18:55:55 +0000740}
741
742static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000743utf32le_encode(textio *self, PyObject *text)
Antoine Pitroue4501852009-05-14 18:55:55 +0000744{
Antoine Pitrou5c398e82011-11-13 04:11:37 +0100745 return _PyUnicode_EncodeUTF32(text,
746 PyBytes_AS_STRING(self->errors), -1);
Antoine Pitroue4501852009-05-14 18:55:55 +0000747}
748
749static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000750utf32_encode(textio *self, PyObject *text)
Antoine Pitroue4501852009-05-14 18:55:55 +0000751{
752 if (!self->encoding_start_of_stream) {
753 /* Skip the BOM and use native byte ordering */
Christian Heimes743e0cd2012-10-17 23:52:17 +0200754#if PY_BIG_ENDIAN
Antoine Pitroue4501852009-05-14 18:55:55 +0000755 return utf32be_encode(self, text);
756#else
757 return utf32le_encode(self, text);
758#endif
759 }
Antoine Pitrou5c398e82011-11-13 04:11:37 +0100760 return _PyUnicode_EncodeUTF32(text,
761 PyBytes_AS_STRING(self->errors), 0);
Antoine Pitroue4501852009-05-14 18:55:55 +0000762}
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000763
764static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000765utf8_encode(textio *self, PyObject *text)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000766{
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200767 return _PyUnicode_AsUTF8String(text, PyBytes_AS_STRING(self->errors));
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000768}
769
770static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +0000771latin1_encode(textio *self, PyObject *text)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000772{
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200773 return _PyUnicode_AsLatin1String(text, PyBytes_AS_STRING(self->errors));
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000774}
775
776/* Map normalized encoding names onto the specialized encoding funcs */
777
778typedef struct {
779 const char *name;
780 encodefunc_t encodefunc;
781} encodefuncentry;
782
Serhiy Storchaka2d06e842015-12-25 19:53:18 +0200783static const encodefuncentry encodefuncs[] = {
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000784 {"ascii", (encodefunc_t) ascii_encode},
785 {"iso8859-1", (encodefunc_t) latin1_encode},
Antoine Pitroue4501852009-05-14 18:55:55 +0000786 {"utf-8", (encodefunc_t) utf8_encode},
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000787 {"utf-16-be", (encodefunc_t) utf16be_encode},
788 {"utf-16-le", (encodefunc_t) utf16le_encode},
789 {"utf-16", (encodefunc_t) utf16_encode},
Antoine Pitroue4501852009-05-14 18:55:55 +0000790 {"utf-32-be", (encodefunc_t) utf32be_encode},
791 {"utf-32-le", (encodefunc_t) utf32le_encode},
792 {"utf-32", (encodefunc_t) utf32_encode},
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000793 {NULL, NULL}
794};
795
796
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300797/*[clinic input]
798_io.TextIOWrapper.__init__
799 buffer: object
Larry Hastingsdbfdc382015-05-04 06:59:46 -0700800 encoding: str(accept={str, NoneType}) = NULL
801 errors: str(accept={str, NoneType}) = NULL
802 newline: str(accept={str, NoneType}) = NULL
Serhiy Storchaka202fda52017-03-12 10:10:47 +0200803 line_buffering: bool(accept={int}) = False
804 write_through: bool(accept={int}) = False
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000805
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300806Character and line based layer over a BufferedIOBase object, buffer.
807
808encoding gives the name of the encoding that the stream will be
809decoded or encoded with. It defaults to locale.getpreferredencoding(False).
810
811errors determines the strictness of encoding and decoding (see
812help(codecs.Codec) or the documentation for codecs.register) and
813defaults to "strict".
814
815newline controls how line endings are handled. It can be None, '',
816'\n', '\r', and '\r\n'. It works as follows:
817
818* On input, if newline is None, universal newlines mode is
819 enabled. Lines in the input can end in '\n', '\r', or '\r\n', and
820 these are translated into '\n' before being returned to the
821 caller. If it is '', universal newline mode is enabled, but line
822 endings are returned to the caller untranslated. If it has any of
823 the other legal values, input lines are only terminated by the given
824 string, and the line ending is returned to the caller untranslated.
825
826* On output, if newline is None, any '\n' characters written are
827 translated to the system default line separator, os.linesep. If
828 newline is '' or '\n', no translation takes place. If newline is any
829 of the other legal values, any '\n' characters written are translated
830 to the given string.
831
832If line_buffering is True, a call to flush is implied when a call to
833write contains a newline character.
834[clinic start generated code]*/
835
836static int
837_io_TextIOWrapper___init___impl(textio *self, PyObject *buffer,
838 const char *encoding, const char *errors,
839 const char *newline, int line_buffering,
840 int write_through)
Serhiy Storchaka202fda52017-03-12 10:10:47 +0200841/*[clinic end generated code: output=56a83402ce2a8381 input=598d10cc5f2ed7dd]*/
Serhiy Storchakaf24131f2015-04-16 11:19:43 +0300842{
843 PyObject *raw, *codec_info = NULL;
844 _PyIO_State *state = NULL;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000845 PyObject *res;
846 int r;
847
848 self->ok = 0;
Benjamin Petersond2e0c792009-05-01 20:40:59 +0000849 self->detached = 0;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000850
851 if (newline && newline[0] != '\0'
852 && !(newline[0] == '\n' && newline[1] == '\0')
853 && !(newline[0] == '\r' && newline[1] == '\0')
854 && !(newline[0] == '\r' && newline[1] == '\n' && newline[2] == '\0')) {
855 PyErr_Format(PyExc_ValueError,
856 "illegal newline value: %s", newline);
857 return -1;
858 }
859
860 Py_CLEAR(self->buffer);
861 Py_CLEAR(self->encoding);
862 Py_CLEAR(self->encoder);
863 Py_CLEAR(self->decoder);
864 Py_CLEAR(self->readnl);
865 Py_CLEAR(self->decoded_chars);
866 Py_CLEAR(self->pending_bytes);
867 Py_CLEAR(self->snapshot);
868 Py_CLEAR(self->errors);
869 Py_CLEAR(self->raw);
870 self->decoded_chars_used = 0;
871 self->pending_bytes_count = 0;
872 self->encodefunc = NULL;
Antoine Pitrou211b81d2011-02-25 20:27:33 +0000873 self->b2cratio = 0.0;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000874
875 if (encoding == NULL) {
876 /* Try os.device_encoding(fileno) */
877 PyObject *fileno;
Antoine Pitrou712cb732013-12-21 15:51:54 +0100878 state = IO_STATE();
879 if (state == NULL)
880 goto error;
Martin v. Löwisafe55bb2011-10-09 10:38:36 +0200881 fileno = _PyObject_CallMethodId(buffer, &PyId_fileno, NULL);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000882 /* Ignore only AttributeError and UnsupportedOperation */
883 if (fileno == NULL) {
884 if (PyErr_ExceptionMatches(PyExc_AttributeError) ||
885 PyErr_ExceptionMatches(state->unsupported_operation)) {
886 PyErr_Clear();
887 }
888 else {
889 goto error;
890 }
891 }
892 else {
Serhiy Storchaka78980432013-01-15 01:12:17 +0200893 int fd = _PyLong_AsInt(fileno);
Brett Cannonefb00c02012-02-29 18:31:31 -0500894 Py_DECREF(fileno);
895 if (fd == -1 && PyErr_Occurred()) {
896 goto error;
897 }
898
899 self->encoding = _Py_device_encoding(fd);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000900 if (self->encoding == NULL)
901 goto error;
902 else if (!PyUnicode_Check(self->encoding))
903 Py_CLEAR(self->encoding);
904 }
905 }
906 if (encoding == NULL && self->encoding == NULL) {
Antoine Pitrou932ff832013-08-01 21:04:50 +0200907 PyObject *locale_module = _PyIO_get_locale_module(state);
908 if (locale_module == NULL)
909 goto catch_ImportError;
Victor Stinner61bdb0d2016-12-09 15:39:28 +0100910 self->encoding = _PyObject_CallMethodIdObjArgs(
911 locale_module, &PyId_getpreferredencoding, Py_False, NULL);
Antoine Pitrou932ff832013-08-01 21:04:50 +0200912 Py_DECREF(locale_module);
913 if (self->encoding == NULL) {
914 catch_ImportError:
915 /*
Martin Panter7462b6492015-11-02 03:37:02 +0000916 Importing locale can raise an ImportError because of
917 _functools, and locale.getpreferredencoding can raise an
Antoine Pitrou932ff832013-08-01 21:04:50 +0200918 ImportError if _locale is not available. These will happen
919 during module building.
920 */
921 if (PyErr_ExceptionMatches(PyExc_ImportError)) {
922 PyErr_Clear();
923 self->encoding = PyUnicode_FromString("ascii");
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000924 }
Antoine Pitrou932ff832013-08-01 21:04:50 +0200925 else
926 goto error;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000927 }
Antoine Pitrou932ff832013-08-01 21:04:50 +0200928 else if (!PyUnicode_Check(self->encoding))
929 Py_CLEAR(self->encoding);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000930 }
Victor Stinnerf6c57832010-05-19 01:17:01 +0000931 if (self->encoding != NULL) {
Serhiy Storchaka06515832016-11-20 09:13:07 +0200932 encoding = PyUnicode_AsUTF8(self->encoding);
Victor Stinnerf6c57832010-05-19 01:17:01 +0000933 if (encoding == NULL)
934 goto error;
935 }
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000936 else if (encoding != NULL) {
937 self->encoding = PyUnicode_FromString(encoding);
938 if (self->encoding == NULL)
939 goto error;
940 }
941 else {
Serhiy Storchaka55fe1ae2017-04-16 10:46:38 +0300942 PyErr_SetString(PyExc_OSError,
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000943 "could not determine default encoding");
944 }
945
Nick Coghlana9b15242014-02-04 22:11:18 +1000946 /* Check we have been asked for a real text encoding */
947 codec_info = _PyCodec_LookupTextEncoding(encoding, "codecs.open()");
948 if (codec_info == NULL) {
949 Py_CLEAR(self->encoding);
950 goto error;
951 }
952
953 /* XXX: Failures beyond this point have the potential to leak elements
954 * of the partially constructed object (like self->encoding)
955 */
956
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000957 if (errors == NULL)
958 errors = "strict";
959 self->errors = PyBytes_FromString(errors);
960 if (self->errors == NULL)
961 goto error;
962
963 self->chunk_size = 8192;
964 self->readuniversal = (newline == NULL || newline[0] == '\0');
965 self->line_buffering = line_buffering;
Antoine Pitroue96ec682011-07-23 21:46:35 +0200966 self->write_through = write_through;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000967 self->readtranslate = (newline == NULL);
968 if (newline) {
969 self->readnl = PyUnicode_FromString(newline);
970 if (self->readnl == NULL)
Nick Coghlana9b15242014-02-04 22:11:18 +1000971 goto error;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000972 }
973 self->writetranslate = (newline == NULL || newline[0] != '\0');
974 if (!self->readuniversal && self->readnl) {
Serhiy Storchaka06515832016-11-20 09:13:07 +0200975 self->writenl = PyUnicode_AsUTF8(self->readnl);
Victor Stinnerf6c57832010-05-19 01:17:01 +0000976 if (self->writenl == NULL)
977 goto error;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000978 if (!strcmp(self->writenl, "\n"))
979 self->writenl = NULL;
980 }
981#ifdef MS_WINDOWS
982 else
983 self->writenl = "\r\n";
984#endif
985
986 /* Build the decoder object */
Martin v. Löwisafe55bb2011-10-09 10:38:36 +0200987 res = _PyObject_CallMethodId(buffer, &PyId_readable, NULL);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000988 if (res == NULL)
989 goto error;
990 r = PyObject_IsTrue(res);
991 Py_DECREF(res);
992 if (r == -1)
993 goto error;
994 if (r == 1) {
Nick Coghlana9b15242014-02-04 22:11:18 +1000995 self->decoder = _PyCodecInfo_GetIncrementalDecoder(codec_info,
996 errors);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +0000997 if (self->decoder == NULL)
998 goto error;
999
1000 if (self->readuniversal) {
1001 PyObject *incrementalDecoder = PyObject_CallFunction(
1002 (PyObject *)&PyIncrementalNewlineDecoder_Type,
1003 "Oi", self->decoder, (int)self->readtranslate);
1004 if (incrementalDecoder == NULL)
1005 goto error;
Serhiy Storchaka48842712016-04-06 09:45:48 +03001006 Py_XSETREF(self->decoder, incrementalDecoder);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001007 }
1008 }
1009
1010 /* Build the encoder object */
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02001011 res = _PyObject_CallMethodId(buffer, &PyId_writable, NULL);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001012 if (res == NULL)
1013 goto error;
1014 r = PyObject_IsTrue(res);
1015 Py_DECREF(res);
1016 if (r == -1)
1017 goto error;
1018 if (r == 1) {
Nick Coghlana9b15242014-02-04 22:11:18 +10001019 self->encoder = _PyCodecInfo_GetIncrementalEncoder(codec_info,
1020 errors);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001021 if (self->encoder == NULL)
1022 goto error;
Martin Panter536d70e2017-01-14 08:23:08 +00001023 /* Get the normalized name of the codec */
Nick Coghlana9b15242014-02-04 22:11:18 +10001024 res = _PyObject_GetAttrId(codec_info, &PyId_name);
Benjamin Peterson2cfca792009-06-06 20:46:48 +00001025 if (res == NULL) {
1026 if (PyErr_ExceptionMatches(PyExc_AttributeError))
1027 PyErr_Clear();
1028 else
1029 goto error;
1030 }
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001031 else if (PyUnicode_Check(res)) {
Serhiy Storchaka2d06e842015-12-25 19:53:18 +02001032 const encodefuncentry *e = encodefuncs;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001033 while (e->name != NULL) {
Serhiy Storchakaf4934ea2016-11-16 10:17:58 +02001034 if (_PyUnicode_EqualToASCIIString(res, e->name)) {
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001035 self->encodefunc = e->encodefunc;
1036 break;
1037 }
1038 e++;
1039 }
1040 }
1041 Py_XDECREF(res);
1042 }
1043
Nick Coghlana9b15242014-02-04 22:11:18 +10001044 /* Finished sorting out the codec details */
Benjamin Peterson6c14f232014-11-12 10:19:46 -05001045 Py_CLEAR(codec_info);
Nick Coghlana9b15242014-02-04 22:11:18 +10001046
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001047 self->buffer = buffer;
1048 Py_INCREF(buffer);
Antoine Pitrou24f36292009-03-28 22:16:42 +00001049
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001050 if (Py_TYPE(buffer) == &PyBufferedReader_Type ||
1051 Py_TYPE(buffer) == &PyBufferedWriter_Type ||
1052 Py_TYPE(buffer) == &PyBufferedRandom_Type) {
Martin v. Löwis767046a2011-10-14 15:35:36 +02001053 raw = _PyObject_GetAttrId(buffer, &PyId_raw);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001054 /* Cache the raw FileIO object to speed up 'closed' checks */
Benjamin Peterson2cfca792009-06-06 20:46:48 +00001055 if (raw == NULL) {
1056 if (PyErr_ExceptionMatches(PyExc_AttributeError))
1057 PyErr_Clear();
1058 else
1059 goto error;
1060 }
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001061 else if (Py_TYPE(raw) == &PyFileIO_Type)
1062 self->raw = raw;
1063 else
1064 Py_DECREF(raw);
1065 }
1066
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02001067 res = _PyObject_CallMethodId(buffer, &PyId_seekable, NULL);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001068 if (res == NULL)
1069 goto error;
Antoine Pitrou6f430e42012-08-15 23:18:25 +02001070 r = PyObject_IsTrue(res);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001071 Py_DECREF(res);
Antoine Pitrou6f430e42012-08-15 23:18:25 +02001072 if (r < 0)
1073 goto error;
1074 self->seekable = self->telling = r;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001075
Martin v. Löwis767046a2011-10-14 15:35:36 +02001076 self->has_read1 = _PyObject_HasAttrId(buffer, &PyId_read1);
Antoine Pitroue96ec682011-07-23 21:46:35 +02001077
Antoine Pitroue4501852009-05-14 18:55:55 +00001078 self->encoding_start_of_stream = 0;
1079 if (self->seekable && self->encoder) {
1080 PyObject *cookieObj;
1081 int cmp;
1082
1083 self->encoding_start_of_stream = 1;
1084
1085 cookieObj = PyObject_CallMethodObjArgs(buffer, _PyIO_str_tell, NULL);
1086 if (cookieObj == NULL)
1087 goto error;
1088
Serhiy Storchakaba85d692017-03-30 09:09:41 +03001089 cmp = PyObject_RichCompareBool(cookieObj, _PyLong_Zero, Py_EQ);
Antoine Pitroue4501852009-05-14 18:55:55 +00001090 Py_DECREF(cookieObj);
1091 if (cmp < 0) {
1092 goto error;
1093 }
1094
1095 if (cmp == 0) {
1096 self->encoding_start_of_stream = 0;
1097 res = PyObject_CallMethodObjArgs(self->encoder, _PyIO_str_setstate,
Serhiy Storchakaba85d692017-03-30 09:09:41 +03001098 _PyLong_Zero, NULL);
Antoine Pitroue4501852009-05-14 18:55:55 +00001099 if (res == NULL)
1100 goto error;
1101 Py_DECREF(res);
1102 }
1103 }
1104
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001105 self->ok = 1;
1106 return 0;
1107
1108 error:
Nick Coghlana9b15242014-02-04 22:11:18 +10001109 Py_XDECREF(codec_info);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001110 return -1;
1111}
1112
Antoine Pitrou3c2817b2017-06-03 12:32:28 +02001113/* Return *default_value* if ob is None, 0 if ob is false, 1 if ob is true,
1114 * -1 on error.
1115 */
1116static int
1117convert_optional_bool(PyObject *obj, int default_value)
1118{
1119 long v;
1120 if (obj == Py_None) {
1121 v = default_value;
1122 }
1123 else {
1124 v = PyLong_AsLong(obj);
1125 if (v == -1 && PyErr_Occurred())
1126 return -1;
1127 }
1128 return v != 0;
1129}
1130
1131
1132/*[clinic input]
1133_io.TextIOWrapper.reconfigure
1134 *
1135 line_buffering as line_buffering_obj: object = None
1136 write_through as write_through_obj: object = None
1137
1138Reconfigure the text stream with new parameters.
1139
1140This also does an implicit stream flush.
1141
1142[clinic start generated code]*/
1143
1144static PyObject *
1145_io_TextIOWrapper_reconfigure_impl(textio *self,
1146 PyObject *line_buffering_obj,
1147 PyObject *write_through_obj)
1148/*[clinic end generated code: output=7cdf79e7001e2856 input=baade27ecb9db7bc]*/
1149{
1150 int line_buffering;
1151 int write_through;
1152 PyObject *res;
1153
1154 line_buffering = convert_optional_bool(line_buffering_obj,
1155 self->line_buffering);
1156 write_through = convert_optional_bool(write_through_obj,
1157 self->write_through);
1158 if (line_buffering < 0 || write_through < 0) {
1159 return NULL;
1160 }
1161 res = PyObject_CallMethodObjArgs((PyObject *) self, _PyIO_str_flush, NULL);
1162 Py_XDECREF(res);
1163 if (res == NULL) {
1164 return NULL;
1165 }
1166 self->line_buffering = line_buffering;
1167 self->write_through = write_through;
1168 Py_RETURN_NONE;
1169}
1170
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001171static int
Serhiy Storchakaa7c972e2016-11-03 15:37:01 +02001172textiowrapper_clear(textio *self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001173{
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001174 self->ok = 0;
1175 Py_CLEAR(self->buffer);
1176 Py_CLEAR(self->encoding);
1177 Py_CLEAR(self->encoder);
1178 Py_CLEAR(self->decoder);
1179 Py_CLEAR(self->readnl);
1180 Py_CLEAR(self->decoded_chars);
1181 Py_CLEAR(self->pending_bytes);
1182 Py_CLEAR(self->snapshot);
1183 Py_CLEAR(self->errors);
1184 Py_CLEAR(self->raw);
Serhiy Storchakaa7c972e2016-11-03 15:37:01 +02001185
1186 Py_CLEAR(self->dict);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001187 return 0;
1188}
1189
1190static void
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001191textiowrapper_dealloc(textio *self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001192{
Antoine Pitrou796564c2013-07-30 19:59:21 +02001193 self->finalizing = 1;
1194 if (_PyIOBase_finalize((PyObject *) self) < 0)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001195 return;
Serhiy Storchakaa7c972e2016-11-03 15:37:01 +02001196 self->ok = 0;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001197 _PyObject_GC_UNTRACK(self);
1198 if (self->weakreflist != NULL)
1199 PyObject_ClearWeakRefs((PyObject *)self);
Serhiy Storchakaa7c972e2016-11-03 15:37:01 +02001200 textiowrapper_clear(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001201 Py_TYPE(self)->tp_free((PyObject *)self);
1202}
1203
1204static int
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001205textiowrapper_traverse(textio *self, visitproc visit, void *arg)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001206{
1207 Py_VISIT(self->buffer);
1208 Py_VISIT(self->encoding);
1209 Py_VISIT(self->encoder);
1210 Py_VISIT(self->decoder);
1211 Py_VISIT(self->readnl);
1212 Py_VISIT(self->decoded_chars);
1213 Py_VISIT(self->pending_bytes);
1214 Py_VISIT(self->snapshot);
1215 Py_VISIT(self->errors);
1216 Py_VISIT(self->raw);
1217
1218 Py_VISIT(self->dict);
1219 return 0;
1220}
1221
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001222static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001223textiowrapper_closed_get(textio *self, void *context);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001224
1225/* This macro takes some shortcuts to make the common case faster. */
1226#define CHECK_CLOSED(self) \
1227 do { \
1228 int r; \
1229 PyObject *_res; \
1230 if (Py_TYPE(self) == &PyTextIOWrapper_Type) { \
1231 if (self->raw != NULL) \
1232 r = _PyFileIO_closed(self->raw); \
1233 else { \
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001234 _res = textiowrapper_closed_get(self, NULL); \
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001235 if (_res == NULL) \
1236 return NULL; \
1237 r = PyObject_IsTrue(_res); \
1238 Py_DECREF(_res); \
1239 if (r < 0) \
1240 return NULL; \
1241 } \
1242 if (r > 0) { \
1243 PyErr_SetString(PyExc_ValueError, \
1244 "I/O operation on closed file."); \
1245 return NULL; \
1246 } \
1247 } \
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001248 else if (_PyIOBase_check_closed((PyObject *)self, Py_True) == NULL) \
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001249 return NULL; \
1250 } while (0)
1251
1252#define CHECK_INITIALIZED(self) \
1253 if (self->ok <= 0) { \
Benjamin Peterson10e76b62014-12-21 20:51:50 -06001254 PyErr_SetString(PyExc_ValueError, \
1255 "I/O operation on uninitialized object"); \
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001256 return NULL; \
1257 }
1258
Benjamin Peterson10e76b62014-12-21 20:51:50 -06001259#define CHECK_ATTACHED(self) \
1260 CHECK_INITIALIZED(self); \
1261 if (self->detached) { \
1262 PyErr_SetString(PyExc_ValueError, \
1263 "underlying buffer has been detached"); \
1264 return NULL; \
1265 }
1266
1267#define CHECK_ATTACHED_INT(self) \
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001268 if (self->ok <= 0) { \
Benjamin Peterson10e76b62014-12-21 20:51:50 -06001269 PyErr_SetString(PyExc_ValueError, \
1270 "I/O operation on uninitialized object"); \
1271 return -1; \
1272 } else if (self->detached) { \
1273 PyErr_SetString(PyExc_ValueError, \
1274 "underlying buffer has been detached"); \
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001275 return -1; \
1276 }
1277
1278
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001279/*[clinic input]
1280_io.TextIOWrapper.detach
1281[clinic start generated code]*/
1282
Benjamin Petersond2e0c792009-05-01 20:40:59 +00001283static PyObject *
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001284_io_TextIOWrapper_detach_impl(textio *self)
1285/*[clinic end generated code: output=7ba3715cd032d5f2 input=e5a71fbda9e1d9f9]*/
Benjamin Petersond2e0c792009-05-01 20:40:59 +00001286{
1287 PyObject *buffer, *res;
Benjamin Peterson10e76b62014-12-21 20:51:50 -06001288 CHECK_ATTACHED(self);
Benjamin Petersond2e0c792009-05-01 20:40:59 +00001289 res = PyObject_CallMethodObjArgs((PyObject *)self, _PyIO_str_flush, NULL);
1290 if (res == NULL)
1291 return NULL;
1292 Py_DECREF(res);
1293 buffer = self->buffer;
1294 self->buffer = NULL;
1295 self->detached = 1;
Benjamin Petersond2e0c792009-05-01 20:40:59 +00001296 return buffer;
1297}
1298
Antoine Pitrou24f36292009-03-28 22:16:42 +00001299/* Flush the internal write buffer. This doesn't explicitly flush the
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001300 underlying buffered object, though. */
1301static int
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001302_textiowrapper_writeflush(textio *self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001303{
Amaury Forgeot d'Arcccd686a2009-08-29 23:00:38 +00001304 PyObject *pending, *b, *ret;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001305
1306 if (self->pending_bytes == NULL)
1307 return 0;
Amaury Forgeot d'Arcccd686a2009-08-29 23:00:38 +00001308
1309 pending = self->pending_bytes;
1310 Py_INCREF(pending);
1311 self->pending_bytes_count = 0;
1312 Py_CLEAR(self->pending_bytes);
1313
1314 b = _PyBytes_Join(_PyIO_empty_bytes, pending);
1315 Py_DECREF(pending);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001316 if (b == NULL)
1317 return -1;
Gregory P. Smithb9817b02013-02-01 13:03:39 -08001318 ret = NULL;
1319 do {
1320 ret = PyObject_CallMethodObjArgs(self->buffer,
1321 _PyIO_str_write, b, NULL);
1322 } while (ret == NULL && _PyIO_trap_eintr());
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001323 Py_DECREF(b);
1324 if (ret == NULL)
1325 return -1;
1326 Py_DECREF(ret);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001327 return 0;
1328}
1329
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001330/*[clinic input]
1331_io.TextIOWrapper.write
1332 text: unicode
1333 /
1334[clinic start generated code]*/
1335
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001336static PyObject *
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001337_io_TextIOWrapper_write_impl(textio *self, PyObject *text)
1338/*[clinic end generated code: output=d2deb0d50771fcec input=fdf19153584a0e44]*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001339{
1340 PyObject *ret;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001341 PyObject *b;
1342 Py_ssize_t textlen;
1343 int haslf = 0;
Antoine Pitrouc644e7c2014-05-09 00:24:50 +02001344 int needflush = 0, text_needflush = 0;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001345
Martin v. Löwisd63a3b82011-09-28 07:41:54 +02001346 if (PyUnicode_READY(text) == -1)
1347 return NULL;
1348
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001349 CHECK_ATTACHED(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001350 CHECK_CLOSED(self);
1351
Antoine Pitrou0d739d72010-09-05 23:01:12 +00001352 if (self->encoder == NULL)
1353 return _unsupported("not writable");
Benjamin Peterson81971ea2009-05-14 22:01:31 +00001354
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001355 Py_INCREF(text);
1356
Martin v. Löwisd63a3b82011-09-28 07:41:54 +02001357 textlen = PyUnicode_GET_LENGTH(text);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001358
1359 if ((self->writetranslate && self->writenl != NULL) || self->line_buffering)
Martin v. Löwisd63a3b82011-09-28 07:41:54 +02001360 if (PyUnicode_FindChar(text, '\n', 0, PyUnicode_GET_LENGTH(text), 1) != -1)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001361 haslf = 1;
1362
1363 if (haslf && self->writetranslate && self->writenl != NULL) {
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02001364 PyObject *newtext = _PyObject_CallMethodId(
1365 text, &PyId_replace, "ss", "\n", self->writenl);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001366 Py_DECREF(text);
1367 if (newtext == NULL)
1368 return NULL;
1369 text = newtext;
1370 }
1371
Antoine Pitroue96ec682011-07-23 21:46:35 +02001372 if (self->write_through)
Antoine Pitrouc644e7c2014-05-09 00:24:50 +02001373 text_needflush = 1;
1374 if (self->line_buffering &&
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001375 (haslf ||
Martin v. Löwisd63a3b82011-09-28 07:41:54 +02001376 PyUnicode_FindChar(text, '\r', 0, PyUnicode_GET_LENGTH(text), 1) != -1))
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001377 needflush = 1;
1378
1379 /* XXX What if we were just reading? */
Antoine Pitroue4501852009-05-14 18:55:55 +00001380 if (self->encodefunc != NULL) {
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001381 b = (*self->encodefunc)((PyObject *) self, text);
Antoine Pitroue4501852009-05-14 18:55:55 +00001382 self->encoding_start_of_stream = 0;
1383 }
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001384 else
1385 b = PyObject_CallMethodObjArgs(self->encoder,
1386 _PyIO_str_encode, text, NULL);
1387 Py_DECREF(text);
1388 if (b == NULL)
1389 return NULL;
Oren Milmana5b4ea12017-08-25 21:14:54 +03001390 if (!PyBytes_Check(b)) {
1391 PyErr_Format(PyExc_TypeError,
1392 "encoder should return a bytes object, not '%.200s'",
1393 Py_TYPE(b)->tp_name);
1394 Py_DECREF(b);
1395 return NULL;
1396 }
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001397
1398 if (self->pending_bytes == NULL) {
1399 self->pending_bytes = PyList_New(0);
1400 if (self->pending_bytes == NULL) {
1401 Py_DECREF(b);
1402 return NULL;
1403 }
1404 self->pending_bytes_count = 0;
1405 }
1406 if (PyList_Append(self->pending_bytes, b) < 0) {
1407 Py_DECREF(b);
1408 return NULL;
1409 }
1410 self->pending_bytes_count += PyBytes_GET_SIZE(b);
1411 Py_DECREF(b);
Antoine Pitrouc644e7c2014-05-09 00:24:50 +02001412 if (self->pending_bytes_count > self->chunk_size || needflush ||
1413 text_needflush) {
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001414 if (_textiowrapper_writeflush(self) < 0)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001415 return NULL;
1416 }
Antoine Pitrou24f36292009-03-28 22:16:42 +00001417
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001418 if (needflush) {
1419 ret = PyObject_CallMethodObjArgs(self->buffer, _PyIO_str_flush, NULL);
1420 if (ret == NULL)
1421 return NULL;
1422 Py_DECREF(ret);
1423 }
1424
1425 Py_CLEAR(self->snapshot);
1426
1427 if (self->decoder) {
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02001428 ret = _PyObject_CallMethodId(self->decoder, &PyId_reset, NULL);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001429 if (ret == NULL)
1430 return NULL;
1431 Py_DECREF(ret);
1432 }
1433
1434 return PyLong_FromSsize_t(textlen);
1435}
1436
1437/* Steal a reference to chars and store it in the decoded_char buffer;
1438 */
1439static void
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001440textiowrapper_set_decoded_chars(textio *self, PyObject *chars)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001441{
Serhiy Storchaka48842712016-04-06 09:45:48 +03001442 Py_XSETREF(self->decoded_chars, chars);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001443 self->decoded_chars_used = 0;
1444}
1445
1446static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001447textiowrapper_get_decoded_chars(textio *self, Py_ssize_t n)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001448{
1449 PyObject *chars;
1450 Py_ssize_t avail;
1451
1452 if (self->decoded_chars == NULL)
1453 return PyUnicode_FromStringAndSize(NULL, 0);
1454
Martin v. Löwisd63a3b82011-09-28 07:41:54 +02001455 /* decoded_chars is guaranteed to be "ready". */
1456 avail = (PyUnicode_GET_LENGTH(self->decoded_chars)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001457 - self->decoded_chars_used);
1458
1459 assert(avail >= 0);
1460
1461 if (n < 0 || n > avail)
1462 n = avail;
1463
1464 if (self->decoded_chars_used > 0 || n < avail) {
Martin v. Löwisd63a3b82011-09-28 07:41:54 +02001465 chars = PyUnicode_Substring(self->decoded_chars,
1466 self->decoded_chars_used,
1467 self->decoded_chars_used + n);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001468 if (chars == NULL)
1469 return NULL;
1470 }
1471 else {
1472 chars = self->decoded_chars;
1473 Py_INCREF(chars);
1474 }
1475
1476 self->decoded_chars_used += n;
1477 return chars;
1478}
1479
1480/* Read and decode the next chunk of data from the BufferedReader.
1481 */
1482static int
Antoine Pitroue5324562011-11-19 00:39:01 +01001483textiowrapper_read_chunk(textio *self, Py_ssize_t size_hint)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001484{
1485 PyObject *dec_buffer = NULL;
1486 PyObject *dec_flags = NULL;
1487 PyObject *input_chunk = NULL;
Antoine Pitroub8503892014-04-29 10:14:02 +02001488 Py_buffer input_chunk_buf;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001489 PyObject *decoded_chars, *chunk_size;
Antoine Pitrou211b81d2011-02-25 20:27:33 +00001490 Py_ssize_t nbytes, nchars;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001491 int eof;
1492
1493 /* The return value is True unless EOF was reached. The decoded string is
1494 * placed in self._decoded_chars (replacing its previous value). The
1495 * entire input chunk is sent to the decoder, though some of it may remain
1496 * buffered in the decoder, yet to be converted.
1497 */
1498
1499 if (self->decoder == NULL) {
Antoine Pitrou0d739d72010-09-05 23:01:12 +00001500 _unsupported("not readable");
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001501 return -1;
1502 }
1503
1504 if (self->telling) {
1505 /* To prepare for tell(), we need to snapshot a point in the file
1506 * where the decoder's input buffer is empty.
1507 */
1508
1509 PyObject *state = PyObject_CallMethodObjArgs(self->decoder,
1510 _PyIO_str_getstate, NULL);
1511 if (state == NULL)
1512 return -1;
1513 /* Given this, we know there was a valid snapshot point
1514 * len(dec_buffer) bytes ago with decoder state (b'', dec_flags).
1515 */
Oren Milmanba7d7362017-08-29 11:58:27 +03001516 if (!PyTuple_Check(state)) {
1517 PyErr_SetString(PyExc_TypeError,
1518 "illegal decoder state");
1519 Py_DECREF(state);
1520 return -1;
1521 }
1522 if (!PyArg_ParseTuple(state,
1523 "OO;illegal decoder state", &dec_buffer, &dec_flags))
1524 {
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001525 Py_DECREF(state);
1526 return -1;
1527 }
Antoine Pitroub8503892014-04-29 10:14:02 +02001528
1529 if (!PyBytes_Check(dec_buffer)) {
1530 PyErr_Format(PyExc_TypeError,
Oren Milmanba7d7362017-08-29 11:58:27 +03001531 "illegal decoder state: the first item should be a "
1532 "bytes object, not '%.200s'",
Antoine Pitroub8503892014-04-29 10:14:02 +02001533 Py_TYPE(dec_buffer)->tp_name);
1534 Py_DECREF(state);
1535 return -1;
1536 }
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001537 Py_INCREF(dec_buffer);
1538 Py_INCREF(dec_flags);
1539 Py_DECREF(state);
1540 }
1541
1542 /* Read a chunk, decode it, and put the result in self._decoded_chars. */
Antoine Pitroue5324562011-11-19 00:39:01 +01001543 if (size_hint > 0) {
Victor Stinnerf8facac2011-11-22 02:30:47 +01001544 size_hint = (Py_ssize_t)(Py_MAX(self->b2cratio, 1.0) * size_hint);
Antoine Pitroue5324562011-11-19 00:39:01 +01001545 }
1546 chunk_size = PyLong_FromSsize_t(Py_MAX(self->chunk_size, size_hint));
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001547 if (chunk_size == NULL)
1548 goto fail;
Antoine Pitroub8503892014-04-29 10:14:02 +02001549
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001550 input_chunk = PyObject_CallMethodObjArgs(self->buffer,
Antoine Pitroue96ec682011-07-23 21:46:35 +02001551 (self->has_read1 ? _PyIO_str_read1: _PyIO_str_read),
1552 chunk_size, NULL);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001553 Py_DECREF(chunk_size);
1554 if (input_chunk == NULL)
1555 goto fail;
Antoine Pitroub8503892014-04-29 10:14:02 +02001556
1557 if (PyObject_GetBuffer(input_chunk, &input_chunk_buf, 0) != 0) {
Serhiy Storchaka94dc6732013-02-03 17:03:31 +02001558 PyErr_Format(PyExc_TypeError,
Antoine Pitroub8503892014-04-29 10:14:02 +02001559 "underlying %s() should have returned a bytes-like object, "
Serhiy Storchaka94dc6732013-02-03 17:03:31 +02001560 "not '%.200s'", (self->has_read1 ? "read1": "read"),
1561 Py_TYPE(input_chunk)->tp_name);
1562 goto fail;
1563 }
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001564
Antoine Pitroub8503892014-04-29 10:14:02 +02001565 nbytes = input_chunk_buf.len;
Antoine Pitrou211b81d2011-02-25 20:27:33 +00001566 eof = (nbytes == 0);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001567 if (Py_TYPE(self->decoder) == &PyIncrementalNewlineDecoder_Type) {
1568 decoded_chars = _PyIncrementalNewlineDecoder_decode(
1569 self->decoder, input_chunk, eof);
1570 }
1571 else {
1572 decoded_chars = PyObject_CallMethodObjArgs(self->decoder,
1573 _PyIO_str_decode, input_chunk, eof ? Py_True : Py_False, NULL);
1574 }
Antoine Pitroub8503892014-04-29 10:14:02 +02001575 PyBuffer_Release(&input_chunk_buf);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001576
Serhiy Storchaka94dc6732013-02-03 17:03:31 +02001577 if (check_decoded(decoded_chars) < 0)
Martin v. Löwisd63a3b82011-09-28 07:41:54 +02001578 goto fail;
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001579 textiowrapper_set_decoded_chars(self, decoded_chars);
Martin v. Löwisd63a3b82011-09-28 07:41:54 +02001580 nchars = PyUnicode_GET_LENGTH(decoded_chars);
Antoine Pitrou211b81d2011-02-25 20:27:33 +00001581 if (nchars > 0)
1582 self->b2cratio = (double) nbytes / nchars;
1583 else
1584 self->b2cratio = 0.0;
1585 if (nchars > 0)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001586 eof = 0;
1587
1588 if (self->telling) {
1589 /* At the snapshot point, len(dec_buffer) bytes before the read, the
1590 * next input to be decoded is dec_buffer + input_chunk.
1591 */
Antoine Pitroub8503892014-04-29 10:14:02 +02001592 PyObject *next_input = dec_buffer;
1593 PyBytes_Concat(&next_input, input_chunk);
1594 if (next_input == NULL) {
1595 dec_buffer = NULL; /* Reference lost to PyBytes_Concat */
Serhiy Storchaka94dc6732013-02-03 17:03:31 +02001596 goto fail;
1597 }
Serhiy Storchaka48842712016-04-06 09:45:48 +03001598 Py_XSETREF(self->snapshot, Py_BuildValue("NN", dec_flags, next_input));
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001599 }
1600 Py_DECREF(input_chunk);
1601
1602 return (eof == 0);
1603
1604 fail:
1605 Py_XDECREF(dec_buffer);
1606 Py_XDECREF(dec_flags);
1607 Py_XDECREF(input_chunk);
1608 return -1;
1609}
1610
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001611/*[clinic input]
1612_io.TextIOWrapper.read
Serhiy Storchaka762bf402017-03-30 09:15:31 +03001613 size as n: Py_ssize_t(accept={int, NoneType}) = -1
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001614 /
1615[clinic start generated code]*/
1616
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001617static PyObject *
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001618_io_TextIOWrapper_read_impl(textio *self, Py_ssize_t n)
Serhiy Storchaka762bf402017-03-30 09:15:31 +03001619/*[clinic end generated code: output=7e651ce6cc6a25a6 input=123eecbfe214aeb8]*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001620{
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001621 PyObject *result = NULL, *chunks = NULL;
1622
Benjamin Peterson10e76b62014-12-21 20:51:50 -06001623 CHECK_ATTACHED(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001624 CHECK_CLOSED(self);
1625
Antoine Pitrou0d739d72010-09-05 23:01:12 +00001626 if (self->decoder == NULL)
1627 return _unsupported("not readable");
Benjamin Petersona1b49012009-03-31 23:11:32 +00001628
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001629 if (_textiowrapper_writeflush(self) < 0)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001630 return NULL;
1631
1632 if (n < 0) {
1633 /* Read everything */
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02001634 PyObject *bytes = _PyObject_CallMethodId(self->buffer, &PyId_read, NULL);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001635 PyObject *decoded;
1636 if (bytes == NULL)
1637 goto fail;
Victor Stinnerfd821132011-05-25 22:01:33 +02001638
1639 if (Py_TYPE(self->decoder) == &PyIncrementalNewlineDecoder_Type)
1640 decoded = _PyIncrementalNewlineDecoder_decode(self->decoder,
1641 bytes, 1);
1642 else
1643 decoded = PyObject_CallMethodObjArgs(
1644 self->decoder, _PyIO_str_decode, bytes, Py_True, NULL);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001645 Py_DECREF(bytes);
Serhiy Storchaka94dc6732013-02-03 17:03:31 +02001646 if (check_decoded(decoded) < 0)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001647 goto fail;
1648
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001649 result = textiowrapper_get_decoded_chars(self, -1);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001650
1651 if (result == NULL) {
1652 Py_DECREF(decoded);
1653 return NULL;
1654 }
1655
1656 PyUnicode_AppendAndDel(&result, decoded);
1657 if (result == NULL)
1658 goto fail;
1659
1660 Py_CLEAR(self->snapshot);
1661 return result;
1662 }
1663 else {
1664 int res = 1;
1665 Py_ssize_t remaining = n;
1666
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001667 result = textiowrapper_get_decoded_chars(self, n);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001668 if (result == NULL)
1669 goto fail;
Martin v. Löwisd63a3b82011-09-28 07:41:54 +02001670 if (PyUnicode_READY(result) == -1)
1671 goto fail;
1672 remaining -= PyUnicode_GET_LENGTH(result);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001673
1674 /* Keep reading chunks until we have n characters to return */
1675 while (remaining > 0) {
Antoine Pitroue5324562011-11-19 00:39:01 +01001676 res = textiowrapper_read_chunk(self, remaining);
Gregory P. Smith51359922012-06-23 23:55:39 -07001677 if (res < 0) {
1678 /* NOTE: PyErr_SetFromErrno() calls PyErr_CheckSignals()
1679 when EINTR occurs so we needn't do it ourselves. */
1680 if (_PyIO_trap_eintr()) {
1681 continue;
1682 }
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001683 goto fail;
Gregory P. Smith51359922012-06-23 23:55:39 -07001684 }
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001685 if (res == 0) /* EOF */
1686 break;
1687 if (chunks == NULL) {
1688 chunks = PyList_New(0);
1689 if (chunks == NULL)
1690 goto fail;
1691 }
Antoine Pitroue5324562011-11-19 00:39:01 +01001692 if (PyUnicode_GET_LENGTH(result) > 0 &&
1693 PyList_Append(chunks, result) < 0)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001694 goto fail;
1695 Py_DECREF(result);
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001696 result = textiowrapper_get_decoded_chars(self, remaining);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001697 if (result == NULL)
1698 goto fail;
Martin v. Löwisd63a3b82011-09-28 07:41:54 +02001699 remaining -= PyUnicode_GET_LENGTH(result);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001700 }
1701 if (chunks != NULL) {
1702 if (result != NULL && PyList_Append(chunks, result) < 0)
1703 goto fail;
Serhiy Storchaka48842712016-04-06 09:45:48 +03001704 Py_XSETREF(result, PyUnicode_Join(_PyIO_empty_str, chunks));
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001705 if (result == NULL)
1706 goto fail;
1707 Py_CLEAR(chunks);
1708 }
1709 return result;
1710 }
1711 fail:
1712 Py_XDECREF(result);
1713 Py_XDECREF(chunks);
1714 return NULL;
1715}
1716
1717
Victor Stinnerf7b8cb62011-09-29 03:28:17 +02001718/* NOTE: `end` must point to the real end of the Py_UCS4 storage,
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001719 that is to the NUL character. Otherwise the function will produce
1720 incorrect results. */
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02001721static const char *
1722find_control_char(int kind, const char *s, const char *end, Py_UCS4 ch)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001723{
Antoine Pitrouc28e2e52011-11-13 03:53:42 +01001724 if (kind == PyUnicode_1BYTE_KIND) {
1725 assert(ch < 256);
1726 return (char *) memchr((void *) s, (char) ch, end - s);
1727 }
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001728 for (;;) {
Martin v. Löwisd63a3b82011-09-28 07:41:54 +02001729 while (PyUnicode_READ(kind, s, 0) > ch)
Martin v. Löwisc47adb02011-10-07 20:55:35 +02001730 s += kind;
Martin v. Löwisd63a3b82011-09-28 07:41:54 +02001731 if (PyUnicode_READ(kind, s, 0) == ch)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001732 return s;
1733 if (s == end)
1734 return NULL;
Martin v. Löwisc47adb02011-10-07 20:55:35 +02001735 s += kind;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001736 }
1737}
1738
1739Py_ssize_t
1740_PyIO_find_line_ending(
1741 int translated, int universal, PyObject *readnl,
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02001742 int kind, const char *start, const char *end, Py_ssize_t *consumed)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001743{
Martin v. Löwisc47adb02011-10-07 20:55:35 +02001744 Py_ssize_t len = ((char*)end - (char*)start)/kind;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001745
1746 if (translated) {
1747 /* Newlines are already translated, only search for \n */
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02001748 const char *pos = find_control_char(kind, start, end, '\n');
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001749 if (pos != NULL)
Martin v. Löwisc47adb02011-10-07 20:55:35 +02001750 return (pos - start)/kind + 1;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001751 else {
1752 *consumed = len;
1753 return -1;
1754 }
1755 }
1756 else if (universal) {
1757 /* Universal newline search. Find any of \r, \r\n, \n
1758 * The decoder ensures that \r\n are not split in two pieces
1759 */
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02001760 const char *s = start;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001761 for (;;) {
Martin v. Löwisd63a3b82011-09-28 07:41:54 +02001762 Py_UCS4 ch;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001763 /* Fast path for non-control chars. The loop always ends
Victor Stinnerf7b8cb62011-09-29 03:28:17 +02001764 since the Unicode string is NUL-terminated. */
Martin v. Löwisd63a3b82011-09-28 07:41:54 +02001765 while (PyUnicode_READ(kind, s, 0) > '\r')
Martin v. Löwisc47adb02011-10-07 20:55:35 +02001766 s += kind;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001767 if (s >= end) {
1768 *consumed = len;
1769 return -1;
1770 }
Martin v. Löwisd63a3b82011-09-28 07:41:54 +02001771 ch = PyUnicode_READ(kind, s, 0);
Martin v. Löwisc47adb02011-10-07 20:55:35 +02001772 s += kind;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001773 if (ch == '\n')
Martin v. Löwisc47adb02011-10-07 20:55:35 +02001774 return (s - start)/kind;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001775 if (ch == '\r') {
Martin v. Löwisd63a3b82011-09-28 07:41:54 +02001776 if (PyUnicode_READ(kind, s, 0) == '\n')
Martin v. Löwisc47adb02011-10-07 20:55:35 +02001777 return (s - start)/kind + 1;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001778 else
Martin v. Löwisc47adb02011-10-07 20:55:35 +02001779 return (s - start)/kind;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001780 }
1781 }
1782 }
1783 else {
1784 /* Non-universal mode. */
Martin v. Löwisd63a3b82011-09-28 07:41:54 +02001785 Py_ssize_t readnl_len = PyUnicode_GET_LENGTH(readnl);
Victor Stinner706768c2014-08-16 01:03:39 +02001786 Py_UCS1 *nl = PyUnicode_1BYTE_DATA(readnl);
Martin v. Löwisd63a3b82011-09-28 07:41:54 +02001787 /* Assume that readnl is an ASCII character. */
1788 assert(PyUnicode_KIND(readnl) == PyUnicode_1BYTE_KIND);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001789 if (readnl_len == 1) {
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02001790 const char *pos = find_control_char(kind, start, end, nl[0]);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001791 if (pos != NULL)
Martin v. Löwisc47adb02011-10-07 20:55:35 +02001792 return (pos - start)/kind + 1;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001793 *consumed = len;
1794 return -1;
1795 }
1796 else {
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02001797 const char *s = start;
1798 const char *e = end - (readnl_len - 1)*kind;
1799 const char *pos;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001800 if (e < s)
1801 e = s;
1802 while (s < e) {
1803 Py_ssize_t i;
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02001804 const char *pos = find_control_char(kind, s, end, nl[0]);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001805 if (pos == NULL || pos >= e)
1806 break;
1807 for (i = 1; i < readnl_len; i++) {
Martin v. Löwisd63a3b82011-09-28 07:41:54 +02001808 if (PyUnicode_READ(kind, pos, i) != nl[i])
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001809 break;
1810 }
1811 if (i == readnl_len)
Martin v. Löwisc47adb02011-10-07 20:55:35 +02001812 return (pos - start)/kind + readnl_len;
1813 s = pos + kind;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001814 }
Martin v. Löwisd63a3b82011-09-28 07:41:54 +02001815 pos = find_control_char(kind, e, end, nl[0]);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001816 if (pos == NULL)
1817 *consumed = len;
1818 else
Martin v. Löwisc47adb02011-10-07 20:55:35 +02001819 *consumed = (pos - start)/kind;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001820 return -1;
1821 }
1822 }
1823}
1824
1825static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001826_textiowrapper_readline(textio *self, Py_ssize_t limit)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001827{
1828 PyObject *line = NULL, *chunks = NULL, *remaining = NULL;
1829 Py_ssize_t start, endpos, chunked, offset_to_buffer;
1830 int res;
1831
1832 CHECK_CLOSED(self);
1833
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001834 if (_textiowrapper_writeflush(self) < 0)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001835 return NULL;
1836
1837 chunked = 0;
1838
1839 while (1) {
Martin v. Löwisd63a3b82011-09-28 07:41:54 +02001840 char *ptr;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001841 Py_ssize_t line_len;
Martin v. Löwisd63a3b82011-09-28 07:41:54 +02001842 int kind;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001843 Py_ssize_t consumed = 0;
1844
1845 /* First, get some data if necessary */
1846 res = 1;
1847 while (!self->decoded_chars ||
Martin v. Löwisd63a3b82011-09-28 07:41:54 +02001848 !PyUnicode_GET_LENGTH(self->decoded_chars)) {
Antoine Pitroue5324562011-11-19 00:39:01 +01001849 res = textiowrapper_read_chunk(self, 0);
Gregory P. Smith51359922012-06-23 23:55:39 -07001850 if (res < 0) {
1851 /* NOTE: PyErr_SetFromErrno() calls PyErr_CheckSignals()
1852 when EINTR occurs so we needn't do it ourselves. */
1853 if (_PyIO_trap_eintr()) {
1854 continue;
1855 }
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001856 goto error;
Gregory P. Smith51359922012-06-23 23:55:39 -07001857 }
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001858 if (res == 0)
1859 break;
1860 }
1861 if (res == 0) {
1862 /* end of file */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001863 textiowrapper_set_decoded_chars(self, NULL);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001864 Py_CLEAR(self->snapshot);
1865 start = endpos = offset_to_buffer = 0;
1866 break;
1867 }
1868
1869 if (remaining == NULL) {
1870 line = self->decoded_chars;
1871 start = self->decoded_chars_used;
1872 offset_to_buffer = 0;
1873 Py_INCREF(line);
1874 }
1875 else {
1876 assert(self->decoded_chars_used == 0);
1877 line = PyUnicode_Concat(remaining, self->decoded_chars);
1878 start = 0;
Martin v. Löwisd63a3b82011-09-28 07:41:54 +02001879 offset_to_buffer = PyUnicode_GET_LENGTH(remaining);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001880 Py_CLEAR(remaining);
1881 if (line == NULL)
1882 goto error;
Martin v. Löwisd63a3b82011-09-28 07:41:54 +02001883 if (PyUnicode_READY(line) == -1)
1884 goto error;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001885 }
1886
Martin v. Löwisd63a3b82011-09-28 07:41:54 +02001887 ptr = PyUnicode_DATA(line);
1888 line_len = PyUnicode_GET_LENGTH(line);
1889 kind = PyUnicode_KIND(line);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001890
1891 endpos = _PyIO_find_line_ending(
1892 self->readtranslate, self->readuniversal, self->readnl,
Martin v. Löwisd63a3b82011-09-28 07:41:54 +02001893 kind,
Martin v. Löwisc47adb02011-10-07 20:55:35 +02001894 ptr + kind * start,
1895 ptr + kind * line_len,
Martin v. Löwisd63a3b82011-09-28 07:41:54 +02001896 &consumed);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001897 if (endpos >= 0) {
1898 endpos += start;
1899 if (limit >= 0 && (endpos - start) + chunked >= limit)
1900 endpos = start + limit - chunked;
1901 break;
1902 }
1903
1904 /* We can put aside up to `endpos` */
1905 endpos = consumed + start;
1906 if (limit >= 0 && (endpos - start) + chunked >= limit) {
1907 /* Didn't find line ending, but reached length limit */
1908 endpos = start + limit - chunked;
1909 break;
1910 }
1911
1912 if (endpos > start) {
1913 /* No line ending seen yet - put aside current data */
1914 PyObject *s;
1915 if (chunks == NULL) {
1916 chunks = PyList_New(0);
1917 if (chunks == NULL)
1918 goto error;
1919 }
Martin v. Löwisd63a3b82011-09-28 07:41:54 +02001920 s = PyUnicode_Substring(line, start, endpos);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001921 if (s == NULL)
1922 goto error;
1923 if (PyList_Append(chunks, s) < 0) {
1924 Py_DECREF(s);
1925 goto error;
1926 }
Martin v. Löwisd63a3b82011-09-28 07:41:54 +02001927 chunked += PyUnicode_GET_LENGTH(s);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001928 Py_DECREF(s);
1929 }
1930 /* There may be some remaining bytes we'll have to prepend to the
1931 next chunk of data */
1932 if (endpos < line_len) {
Martin v. Löwisd63a3b82011-09-28 07:41:54 +02001933 remaining = PyUnicode_Substring(line, endpos, line_len);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001934 if (remaining == NULL)
1935 goto error;
1936 }
1937 Py_CLEAR(line);
1938 /* We have consumed the buffer */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00001939 textiowrapper_set_decoded_chars(self, NULL);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001940 }
1941
1942 if (line != NULL) {
1943 /* Our line ends in the current buffer */
1944 self->decoded_chars_used = endpos - offset_to_buffer;
Martin v. Löwisd63a3b82011-09-28 07:41:54 +02001945 if (start > 0 || endpos < PyUnicode_GET_LENGTH(line)) {
1946 PyObject *s = PyUnicode_Substring(line, start, endpos);
1947 Py_CLEAR(line);
1948 if (s == NULL)
1949 goto error;
1950 line = s;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001951 }
1952 }
1953 if (remaining != NULL) {
1954 if (chunks == NULL) {
1955 chunks = PyList_New(0);
1956 if (chunks == NULL)
1957 goto error;
1958 }
1959 if (PyList_Append(chunks, remaining) < 0)
1960 goto error;
1961 Py_CLEAR(remaining);
1962 }
1963 if (chunks != NULL) {
Martin v. Löwisd63a3b82011-09-28 07:41:54 +02001964 if (line != NULL) {
1965 if (PyList_Append(chunks, line) < 0)
1966 goto error;
1967 Py_DECREF(line);
1968 }
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001969 line = PyUnicode_Join(_PyIO_empty_str, chunks);
1970 if (line == NULL)
1971 goto error;
Martin v. Löwisd63a3b82011-09-28 07:41:54 +02001972 Py_CLEAR(chunks);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001973 }
Martin v. Löwisd63a3b82011-09-28 07:41:54 +02001974 if (line == NULL) {
1975 Py_INCREF(_PyIO_empty_str);
1976 line = _PyIO_empty_str;
1977 }
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001978
1979 return line;
1980
1981 error:
1982 Py_XDECREF(chunks);
1983 Py_XDECREF(remaining);
1984 Py_XDECREF(line);
1985 return NULL;
1986}
1987
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001988/*[clinic input]
1989_io.TextIOWrapper.readline
1990 size: Py_ssize_t = -1
1991 /
1992[clinic start generated code]*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001993
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001994static PyObject *
1995_io_TextIOWrapper_readline_impl(textio *self, Py_ssize_t size)
1996/*[clinic end generated code: output=344afa98804e8b25 input=56c7172483b36db6]*/
1997{
Benjamin Peterson10e76b62014-12-21 20:51:50 -06001998 CHECK_ATTACHED(self);
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03001999 return _textiowrapper_readline(self, size);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002000}
2001
2002/* Seek and Tell */
2003
2004typedef struct {
2005 Py_off_t start_pos;
2006 int dec_flags;
2007 int bytes_to_feed;
2008 int chars_to_skip;
2009 char need_eof;
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002010} cookie_type;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002011
2012/*
2013 To speed up cookie packing/unpacking, we store the fields in a temporary
2014 string and call _PyLong_FromByteArray() or _PyLong_AsByteArray (resp.).
2015 The following macros define at which offsets in the intermediary byte
2016 string the various CookieStruct fields will be stored.
2017 */
2018
2019#define COOKIE_BUF_LEN (sizeof(Py_off_t) + 3 * sizeof(int) + sizeof(char))
2020
Christian Heimes743e0cd2012-10-17 23:52:17 +02002021#if PY_BIG_ENDIAN
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002022/* We want the least significant byte of start_pos to also be the least
2023 significant byte of the cookie, which means that in big-endian mode we
2024 must copy the fields in reverse order. */
2025
2026# define OFF_START_POS (sizeof(char) + 3 * sizeof(int))
2027# define OFF_DEC_FLAGS (sizeof(char) + 2 * sizeof(int))
2028# define OFF_BYTES_TO_FEED (sizeof(char) + sizeof(int))
2029# define OFF_CHARS_TO_SKIP (sizeof(char))
2030# define OFF_NEED_EOF 0
2031
2032#else
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002033/* Little-endian mode: the least significant byte of start_pos will
2034 naturally end up the least significant byte of the cookie. */
2035
2036# define OFF_START_POS 0
2037# define OFF_DEC_FLAGS (sizeof(Py_off_t))
2038# define OFF_BYTES_TO_FEED (sizeof(Py_off_t) + sizeof(int))
2039# define OFF_CHARS_TO_SKIP (sizeof(Py_off_t) + 2 * sizeof(int))
2040# define OFF_NEED_EOF (sizeof(Py_off_t) + 3 * sizeof(int))
2041
2042#endif
2043
2044static int
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002045textiowrapper_parse_cookie(cookie_type *cookie, PyObject *cookieObj)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002046{
2047 unsigned char buffer[COOKIE_BUF_LEN];
2048 PyLongObject *cookieLong = (PyLongObject *)PyNumber_Long(cookieObj);
2049 if (cookieLong == NULL)
2050 return -1;
2051
2052 if (_PyLong_AsByteArray(cookieLong, buffer, sizeof(buffer),
Christian Heimes743e0cd2012-10-17 23:52:17 +02002053 PY_LITTLE_ENDIAN, 0) < 0) {
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002054 Py_DECREF(cookieLong);
2055 return -1;
2056 }
2057 Py_DECREF(cookieLong);
2058
Antoine Pitrou2db74c22009-03-06 21:49:02 +00002059 memcpy(&cookie->start_pos, buffer + OFF_START_POS, sizeof(cookie->start_pos));
2060 memcpy(&cookie->dec_flags, buffer + OFF_DEC_FLAGS, sizeof(cookie->dec_flags));
2061 memcpy(&cookie->bytes_to_feed, buffer + OFF_BYTES_TO_FEED, sizeof(cookie->bytes_to_feed));
2062 memcpy(&cookie->chars_to_skip, buffer + OFF_CHARS_TO_SKIP, sizeof(cookie->chars_to_skip));
2063 memcpy(&cookie->need_eof, buffer + OFF_NEED_EOF, sizeof(cookie->need_eof));
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002064
2065 return 0;
2066}
2067
2068static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002069textiowrapper_build_cookie(cookie_type *cookie)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002070{
2071 unsigned char buffer[COOKIE_BUF_LEN];
2072
Antoine Pitrou2db74c22009-03-06 21:49:02 +00002073 memcpy(buffer + OFF_START_POS, &cookie->start_pos, sizeof(cookie->start_pos));
2074 memcpy(buffer + OFF_DEC_FLAGS, &cookie->dec_flags, sizeof(cookie->dec_flags));
2075 memcpy(buffer + OFF_BYTES_TO_FEED, &cookie->bytes_to_feed, sizeof(cookie->bytes_to_feed));
2076 memcpy(buffer + OFF_CHARS_TO_SKIP, &cookie->chars_to_skip, sizeof(cookie->chars_to_skip));
2077 memcpy(buffer + OFF_NEED_EOF, &cookie->need_eof, sizeof(cookie->need_eof));
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002078
Christian Heimes743e0cd2012-10-17 23:52:17 +02002079 return _PyLong_FromByteArray(buffer, sizeof(buffer),
2080 PY_LITTLE_ENDIAN, 0);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002081}
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002082
2083static int
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002084_textiowrapper_decoder_setstate(textio *self, cookie_type *cookie)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002085{
2086 PyObject *res;
2087 /* When seeking to the start of the stream, we call decoder.reset()
2088 rather than decoder.getstate().
2089 This is for a few decoders such as utf-16 for which the state value
2090 at start is not (b"", 0) but e.g. (b"", 2) (meaning, in the case of
2091 utf-16, that we are expecting a BOM).
2092 */
2093 if (cookie->start_pos == 0 && cookie->dec_flags == 0)
2094 res = PyObject_CallMethodObjArgs(self->decoder, _PyIO_str_reset, NULL);
2095 else
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02002096 res = _PyObject_CallMethodId(self->decoder, &PyId_setstate,
2097 "((yi))", "", cookie->dec_flags);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002098 if (res == NULL)
2099 return -1;
2100 Py_DECREF(res);
2101 return 0;
2102}
2103
Antoine Pitroue4501852009-05-14 18:55:55 +00002104static int
Antoine Pitrou85e3ee72015-04-13 20:01:21 +02002105_textiowrapper_encoder_reset(textio *self, int start_of_stream)
Antoine Pitroue4501852009-05-14 18:55:55 +00002106{
2107 PyObject *res;
Antoine Pitrou85e3ee72015-04-13 20:01:21 +02002108 if (start_of_stream) {
Antoine Pitroue4501852009-05-14 18:55:55 +00002109 res = PyObject_CallMethodObjArgs(self->encoder, _PyIO_str_reset, NULL);
2110 self->encoding_start_of_stream = 1;
2111 }
2112 else {
2113 res = PyObject_CallMethodObjArgs(self->encoder, _PyIO_str_setstate,
Serhiy Storchakaba85d692017-03-30 09:09:41 +03002114 _PyLong_Zero, NULL);
Antoine Pitroue4501852009-05-14 18:55:55 +00002115 self->encoding_start_of_stream = 0;
2116 }
2117 if (res == NULL)
2118 return -1;
2119 Py_DECREF(res);
2120 return 0;
2121}
2122
Antoine Pitrou85e3ee72015-04-13 20:01:21 +02002123static int
2124_textiowrapper_encoder_setstate(textio *self, cookie_type *cookie)
2125{
2126 /* Same as _textiowrapper_decoder_setstate() above. */
2127 return _textiowrapper_encoder_reset(
2128 self, cookie->start_pos == 0 && cookie->dec_flags == 0);
2129}
2130
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03002131/*[clinic input]
2132_io.TextIOWrapper.seek
2133 cookie as cookieObj: object
2134 whence: int = 0
2135 /
2136[clinic start generated code]*/
2137
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002138static PyObject *
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03002139_io_TextIOWrapper_seek_impl(textio *self, PyObject *cookieObj, int whence)
2140/*[clinic end generated code: output=0a15679764e2d04d input=0458abeb3d7842be]*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002141{
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03002142 PyObject *posobj;
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002143 cookie_type cookie;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002144 PyObject *res;
2145 int cmp;
2146
Benjamin Peterson10e76b62014-12-21 20:51:50 -06002147 CHECK_ATTACHED(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002148 CHECK_CLOSED(self);
2149
2150 Py_INCREF(cookieObj);
2151
2152 if (!self->seekable) {
Antoine Pitrou0d739d72010-09-05 23:01:12 +00002153 _unsupported("underlying stream is not seekable");
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002154 goto fail;
2155 }
2156
2157 if (whence == 1) {
2158 /* seek relative to current position */
Serhiy Storchakaba85d692017-03-30 09:09:41 +03002159 cmp = PyObject_RichCompareBool(cookieObj, _PyLong_Zero, Py_EQ);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002160 if (cmp < 0)
2161 goto fail;
2162
2163 if (cmp == 0) {
Antoine Pitrou0d739d72010-09-05 23:01:12 +00002164 _unsupported("can't do nonzero cur-relative seeks");
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002165 goto fail;
2166 }
2167
2168 /* Seeking to the current position should attempt to
2169 * sync the underlying buffer with the current position.
2170 */
2171 Py_DECREF(cookieObj);
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02002172 cookieObj = _PyObject_CallMethodId((PyObject *)self, &PyId_tell, NULL);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002173 if (cookieObj == NULL)
2174 goto fail;
2175 }
2176 else if (whence == 2) {
2177 /* seek relative to end of file */
Serhiy Storchakaba85d692017-03-30 09:09:41 +03002178 cmp = PyObject_RichCompareBool(cookieObj, _PyLong_Zero, Py_EQ);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002179 if (cmp < 0)
2180 goto fail;
2181
2182 if (cmp == 0) {
Antoine Pitrou0d739d72010-09-05 23:01:12 +00002183 _unsupported("can't do nonzero end-relative seeks");
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002184 goto fail;
2185 }
2186
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02002187 res = _PyObject_CallMethodId((PyObject *)self, &PyId_flush, NULL);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002188 if (res == NULL)
2189 goto fail;
2190 Py_DECREF(res);
2191
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002192 textiowrapper_set_decoded_chars(self, NULL);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002193 Py_CLEAR(self->snapshot);
2194 if (self->decoder) {
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02002195 res = _PyObject_CallMethodId(self->decoder, &PyId_reset, NULL);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002196 if (res == NULL)
2197 goto fail;
2198 Py_DECREF(res);
2199 }
2200
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02002201 res = _PyObject_CallMethodId(self->buffer, &PyId_seek, "ii", 0, 2);
Antoine Pitrou85e3ee72015-04-13 20:01:21 +02002202 Py_CLEAR(cookieObj);
2203 if (res == NULL)
2204 goto fail;
2205 if (self->encoder) {
2206 /* If seek() == 0, we are at the start of stream, otherwise not */
Serhiy Storchakaba85d692017-03-30 09:09:41 +03002207 cmp = PyObject_RichCompareBool(res, _PyLong_Zero, Py_EQ);
Antoine Pitrou85e3ee72015-04-13 20:01:21 +02002208 if (cmp < 0 || _textiowrapper_encoder_reset(self, cmp)) {
2209 Py_DECREF(res);
2210 goto fail;
2211 }
2212 }
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002213 return res;
2214 }
2215 else if (whence != 0) {
2216 PyErr_Format(PyExc_ValueError,
2217 "invalid whence (%d, should be 0, 1 or 2)", whence);
2218 goto fail;
2219 }
2220
Serhiy Storchakaba85d692017-03-30 09:09:41 +03002221 cmp = PyObject_RichCompareBool(cookieObj, _PyLong_Zero, Py_LT);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002222 if (cmp < 0)
2223 goto fail;
2224
2225 if (cmp == 1) {
2226 PyErr_Format(PyExc_ValueError,
2227 "negative seek position %R", cookieObj);
2228 goto fail;
2229 }
2230
2231 res = PyObject_CallMethodObjArgs((PyObject *)self, _PyIO_str_flush, NULL);
2232 if (res == NULL)
2233 goto fail;
2234 Py_DECREF(res);
2235
2236 /* The strategy of seek() is to go back to the safe start point
2237 * and replay the effect of read(chars_to_skip) from there.
2238 */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002239 if (textiowrapper_parse_cookie(&cookie, cookieObj) < 0)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002240 goto fail;
2241
2242 /* Seek back to the safe start point. */
2243 posobj = PyLong_FromOff_t(cookie.start_pos);
2244 if (posobj == NULL)
2245 goto fail;
2246 res = PyObject_CallMethodObjArgs(self->buffer,
2247 _PyIO_str_seek, posobj, NULL);
2248 Py_DECREF(posobj);
2249 if (res == NULL)
2250 goto fail;
2251 Py_DECREF(res);
2252
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002253 textiowrapper_set_decoded_chars(self, NULL);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002254 Py_CLEAR(self->snapshot);
2255
2256 /* Restore the decoder to its state from the safe start point. */
2257 if (self->decoder) {
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002258 if (_textiowrapper_decoder_setstate(self, &cookie) < 0)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002259 goto fail;
2260 }
2261
2262 if (cookie.chars_to_skip) {
2263 /* Just like _read_chunk, feed the decoder and save a snapshot. */
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02002264 PyObject *input_chunk = _PyObject_CallMethodId(
2265 self->buffer, &PyId_read, "i", cookie.bytes_to_feed);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002266 PyObject *decoded;
2267
2268 if (input_chunk == NULL)
2269 goto fail;
2270
Serhiy Storchaka94dc6732013-02-03 17:03:31 +02002271 if (!PyBytes_Check(input_chunk)) {
2272 PyErr_Format(PyExc_TypeError,
2273 "underlying read() should have returned a bytes "
2274 "object, not '%.200s'",
2275 Py_TYPE(input_chunk)->tp_name);
2276 Py_DECREF(input_chunk);
2277 goto fail;
2278 }
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002279
2280 self->snapshot = Py_BuildValue("iN", cookie.dec_flags, input_chunk);
2281 if (self->snapshot == NULL) {
2282 Py_DECREF(input_chunk);
2283 goto fail;
2284 }
2285
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02002286 decoded = _PyObject_CallMethodId(self->decoder, &PyId_decode,
2287 "Oi", input_chunk, (int)cookie.need_eof);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002288
Serhiy Storchaka94dc6732013-02-03 17:03:31 +02002289 if (check_decoded(decoded) < 0)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002290 goto fail;
2291
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002292 textiowrapper_set_decoded_chars(self, decoded);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002293
2294 /* Skip chars_to_skip of the decoded characters. */
Victor Stinner9e30aa52011-11-21 02:49:52 +01002295 if (PyUnicode_GetLength(self->decoded_chars) < cookie.chars_to_skip) {
Serhiy Storchaka55fe1ae2017-04-16 10:46:38 +03002296 PyErr_SetString(PyExc_OSError, "can't restore logical file position");
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002297 goto fail;
2298 }
2299 self->decoded_chars_used = cookie.chars_to_skip;
2300 }
2301 else {
2302 self->snapshot = Py_BuildValue("iy", cookie.dec_flags, "");
2303 if (self->snapshot == NULL)
2304 goto fail;
2305 }
2306
Antoine Pitroue4501852009-05-14 18:55:55 +00002307 /* Finally, reset the encoder (merely useful for proper BOM handling) */
2308 if (self->encoder) {
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002309 if (_textiowrapper_encoder_setstate(self, &cookie) < 0)
Antoine Pitroue4501852009-05-14 18:55:55 +00002310 goto fail;
2311 }
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002312 return cookieObj;
2313 fail:
2314 Py_XDECREF(cookieObj);
2315 return NULL;
2316
2317}
2318
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03002319/*[clinic input]
2320_io.TextIOWrapper.tell
2321[clinic start generated code]*/
2322
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002323static PyObject *
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03002324_io_TextIOWrapper_tell_impl(textio *self)
2325/*[clinic end generated code: output=4f168c08bf34ad5f input=9a2caf88c24f9ddf]*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002326{
2327 PyObject *res;
2328 PyObject *posobj = NULL;
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002329 cookie_type cookie = {0,0,0,0,0};
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002330 PyObject *next_input;
2331 Py_ssize_t chars_to_skip, chars_decoded;
Antoine Pitrou211b81d2011-02-25 20:27:33 +00002332 Py_ssize_t skip_bytes, skip_back;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002333 PyObject *saved_state = NULL;
2334 char *input, *input_end;
Antoine Pitrou211b81d2011-02-25 20:27:33 +00002335 Py_ssize_t dec_buffer_len;
2336 int dec_flags;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002337
Benjamin Peterson10e76b62014-12-21 20:51:50 -06002338 CHECK_ATTACHED(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002339 CHECK_CLOSED(self);
2340
2341 if (!self->seekable) {
Antoine Pitrou0d739d72010-09-05 23:01:12 +00002342 _unsupported("underlying stream is not seekable");
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002343 goto fail;
2344 }
2345 if (!self->telling) {
Serhiy Storchaka55fe1ae2017-04-16 10:46:38 +03002346 PyErr_SetString(PyExc_OSError,
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002347 "telling position disabled by next() call");
2348 goto fail;
2349 }
2350
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002351 if (_textiowrapper_writeflush(self) < 0)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002352 return NULL;
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02002353 res = _PyObject_CallMethodId((PyObject *)self, &PyId_flush, NULL);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002354 if (res == NULL)
2355 goto fail;
2356 Py_DECREF(res);
2357
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02002358 posobj = _PyObject_CallMethodId(self->buffer, &PyId_tell, NULL);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002359 if (posobj == NULL)
2360 goto fail;
2361
2362 if (self->decoder == NULL || self->snapshot == NULL) {
Victor Stinner9e30aa52011-11-21 02:49:52 +01002363 assert (self->decoded_chars == NULL || PyUnicode_GetLength(self->decoded_chars) == 0);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002364 return posobj;
2365 }
2366
2367#if defined(HAVE_LARGEFILE_SUPPORT)
2368 cookie.start_pos = PyLong_AsLongLong(posobj);
2369#else
2370 cookie.start_pos = PyLong_AsLong(posobj);
2371#endif
Antoine Pitrou211b81d2011-02-25 20:27:33 +00002372 Py_DECREF(posobj);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002373 if (PyErr_Occurred())
2374 goto fail;
2375
2376 /* Skip backward to the snapshot point (see _read_chunk). */
Oren Milman13614e32017-08-24 19:51:24 +03002377 assert(PyTuple_Check(self->snapshot));
Serhiy Storchakabb72c472015-04-19 20:38:19 +03002378 if (!PyArg_ParseTuple(self->snapshot, "iO", &cookie.dec_flags, &next_input))
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002379 goto fail;
2380
2381 assert (PyBytes_Check(next_input));
2382
2383 cookie.start_pos -= PyBytes_GET_SIZE(next_input);
2384
2385 /* How many decoded characters have been used up since the snapshot? */
2386 if (self->decoded_chars_used == 0) {
2387 /* We haven't moved from the snapshot point. */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002388 return textiowrapper_build_cookie(&cookie);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002389 }
2390
2391 chars_to_skip = self->decoded_chars_used;
2392
Antoine Pitrou211b81d2011-02-25 20:27:33 +00002393 /* Decoder state will be restored at the end */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002394 saved_state = PyObject_CallMethodObjArgs(self->decoder,
2395 _PyIO_str_getstate, NULL);
2396 if (saved_state == NULL)
2397 goto fail;
2398
Antoine Pitrou211b81d2011-02-25 20:27:33 +00002399#define DECODER_GETSTATE() do { \
Serhiy Storchaka008d88b2015-05-06 09:53:07 +03002400 PyObject *dec_buffer; \
Antoine Pitrou211b81d2011-02-25 20:27:33 +00002401 PyObject *_state = PyObject_CallMethodObjArgs(self->decoder, \
2402 _PyIO_str_getstate, NULL); \
2403 if (_state == NULL) \
2404 goto fail; \
Oren Milman13614e32017-08-24 19:51:24 +03002405 if (!PyTuple_Check(_state)) { \
2406 PyErr_SetString(PyExc_TypeError, \
2407 "illegal decoder state"); \
2408 Py_DECREF(_state); \
2409 goto fail; \
2410 } \
2411 if (!PyArg_ParseTuple(_state, "Oi;illegal decoder state", \
2412 &dec_buffer, &dec_flags)) \
2413 { \
Antoine Pitrou211b81d2011-02-25 20:27:33 +00002414 Py_DECREF(_state); \
2415 goto fail; \
2416 } \
Serhiy Storchaka008d88b2015-05-06 09:53:07 +03002417 if (!PyBytes_Check(dec_buffer)) { \
2418 PyErr_Format(PyExc_TypeError, \
Oren Milmanba7d7362017-08-29 11:58:27 +03002419 "illegal decoder state: the first item should be a " \
2420 "bytes object, not '%.200s'", \
Serhiy Storchaka008d88b2015-05-06 09:53:07 +03002421 Py_TYPE(dec_buffer)->tp_name); \
2422 Py_DECREF(_state); \
2423 goto fail; \
2424 } \
2425 dec_buffer_len = PyBytes_GET_SIZE(dec_buffer); \
Antoine Pitrou211b81d2011-02-25 20:27:33 +00002426 Py_DECREF(_state); \
2427 } while (0)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002428
Antoine Pitrou211b81d2011-02-25 20:27:33 +00002429#define DECODER_DECODE(start, len, res) do { \
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02002430 PyObject *_decoded = _PyObject_CallMethodId( \
2431 self->decoder, &PyId_decode, "y#", start, len); \
Serhiy Storchakad03ce4a2013-02-03 17:07:32 +02002432 if (check_decoded(_decoded) < 0) \
Antoine Pitrou211b81d2011-02-25 20:27:33 +00002433 goto fail; \
Martin v. Löwisd63a3b82011-09-28 07:41:54 +02002434 res = PyUnicode_GET_LENGTH(_decoded); \
Antoine Pitrou211b81d2011-02-25 20:27:33 +00002435 Py_DECREF(_decoded); \
2436 } while (0)
2437
2438 /* Fast search for an acceptable start point, close to our
2439 current pos */
2440 skip_bytes = (Py_ssize_t) (self->b2cratio * chars_to_skip);
2441 skip_back = 1;
2442 assert(skip_back <= PyBytes_GET_SIZE(next_input));
2443 input = PyBytes_AS_STRING(next_input);
2444 while (skip_bytes > 0) {
2445 /* Decode up to temptative start point */
2446 if (_textiowrapper_decoder_setstate(self, &cookie) < 0)
2447 goto fail;
2448 DECODER_DECODE(input, skip_bytes, chars_decoded);
2449 if (chars_decoded <= chars_to_skip) {
2450 DECODER_GETSTATE();
2451 if (dec_buffer_len == 0) {
2452 /* Before pos and no bytes buffered in decoder => OK */
2453 cookie.dec_flags = dec_flags;
2454 chars_to_skip -= chars_decoded;
2455 break;
2456 }
2457 /* Skip back by buffered amount and reset heuristic */
2458 skip_bytes -= dec_buffer_len;
2459 skip_back = 1;
2460 }
2461 else {
2462 /* We're too far ahead, skip back a bit */
2463 skip_bytes -= skip_back;
2464 skip_back *= 2;
2465 }
2466 }
2467 if (skip_bytes <= 0) {
2468 skip_bytes = 0;
2469 if (_textiowrapper_decoder_setstate(self, &cookie) < 0)
2470 goto fail;
2471 }
2472
2473 /* Note our initial start point. */
2474 cookie.start_pos += skip_bytes;
Victor Stinner9a282972013-06-24 23:01:33 +02002475 cookie.chars_to_skip = Py_SAFE_DOWNCAST(chars_to_skip, Py_ssize_t, int);
Antoine Pitrou211b81d2011-02-25 20:27:33 +00002476 if (chars_to_skip == 0)
2477 goto finally;
2478
2479 /* We should be close to the desired position. Now feed the decoder one
2480 * byte at a time until we reach the `chars_to_skip` target.
2481 * As we go, note the nearest "safe start point" before the current
2482 * location (a point where the decoder has nothing buffered, so seek()
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002483 * can safely start from there and advance to this location).
2484 */
2485 chars_decoded = 0;
2486 input = PyBytes_AS_STRING(next_input);
2487 input_end = input + PyBytes_GET_SIZE(next_input);
Antoine Pitrou211b81d2011-02-25 20:27:33 +00002488 input += skip_bytes;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002489 while (input < input_end) {
Antoine Pitrou211b81d2011-02-25 20:27:33 +00002490 Py_ssize_t n;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002491
Serhiy Storchakaec67d182013-08-20 20:04:47 +03002492 DECODER_DECODE(input, (Py_ssize_t)1, n);
Antoine Pitrou211b81d2011-02-25 20:27:33 +00002493 /* We got n chars for 1 byte */
2494 chars_decoded += n;
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002495 cookie.bytes_to_feed += 1;
Antoine Pitrou211b81d2011-02-25 20:27:33 +00002496 DECODER_GETSTATE();
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002497
2498 if (dec_buffer_len == 0 && chars_decoded <= chars_to_skip) {
2499 /* Decoder buffer is empty, so this is a safe start point. */
2500 cookie.start_pos += cookie.bytes_to_feed;
2501 chars_to_skip -= chars_decoded;
2502 cookie.dec_flags = dec_flags;
2503 cookie.bytes_to_feed = 0;
2504 chars_decoded = 0;
2505 }
2506 if (chars_decoded >= chars_to_skip)
2507 break;
2508 input++;
2509 }
2510 if (input == input_end) {
2511 /* We didn't get enough decoded data; signal EOF to get more. */
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02002512 PyObject *decoded = _PyObject_CallMethodId(
2513 self->decoder, &PyId_decode, "yi", "", /* final = */ 1);
Serhiy Storchaka94dc6732013-02-03 17:03:31 +02002514 if (check_decoded(decoded) < 0)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002515 goto fail;
Martin v. Löwisd63a3b82011-09-28 07:41:54 +02002516 chars_decoded += PyUnicode_GET_LENGTH(decoded);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002517 Py_DECREF(decoded);
2518 cookie.need_eof = 1;
2519
2520 if (chars_decoded < chars_to_skip) {
Serhiy Storchaka55fe1ae2017-04-16 10:46:38 +03002521 PyErr_SetString(PyExc_OSError,
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002522 "can't reconstruct logical file position");
2523 goto fail;
2524 }
2525 }
2526
Antoine Pitrou211b81d2011-02-25 20:27:33 +00002527finally:
Victor Stinner7e425412016-12-09 00:36:19 +01002528 res = _PyObject_CallMethodIdObjArgs(self->decoder, &PyId_setstate, saved_state, NULL);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002529 Py_DECREF(saved_state);
2530 if (res == NULL)
2531 return NULL;
2532 Py_DECREF(res);
2533
2534 /* The returned cookie corresponds to the last safe start point. */
2535 cookie.chars_to_skip = Py_SAFE_DOWNCAST(chars_to_skip, Py_ssize_t, int);
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002536 return textiowrapper_build_cookie(&cookie);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002537
Antoine Pitrou211b81d2011-02-25 20:27:33 +00002538fail:
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002539 if (saved_state) {
2540 PyObject *type, *value, *traceback;
2541 PyErr_Fetch(&type, &value, &traceback);
Victor Stinner7e425412016-12-09 00:36:19 +01002542 res = _PyObject_CallMethodIdObjArgs(self->decoder, &PyId_setstate, saved_state, NULL);
Serhiy Storchaka04d09eb2015-03-30 09:58:41 +03002543 _PyErr_ChainExceptions(type, value, traceback);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002544 Py_DECREF(saved_state);
Serhiy Storchaka04d09eb2015-03-30 09:58:41 +03002545 Py_XDECREF(res);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002546 }
2547 return NULL;
2548}
2549
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03002550/*[clinic input]
2551_io.TextIOWrapper.truncate
2552 pos: object = None
2553 /
2554[clinic start generated code]*/
2555
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002556static PyObject *
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03002557_io_TextIOWrapper_truncate_impl(textio *self, PyObject *pos)
2558/*[clinic end generated code: output=90ec2afb9bb7745f input=56ec8baa65aea377]*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002559{
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002560 PyObject *res;
2561
Benjamin Peterson10e76b62014-12-21 20:51:50 -06002562 CHECK_ATTACHED(self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002563
2564 res = PyObject_CallMethodObjArgs((PyObject *) self, _PyIO_str_flush, NULL);
2565 if (res == NULL)
2566 return NULL;
2567 Py_DECREF(res);
2568
Antoine Pitrou905a2ff2010-01-31 22:47:27 +00002569 return PyObject_CallMethodObjArgs(self->buffer, _PyIO_str_truncate, pos, NULL);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002570}
2571
Benjamin Petersonc4c0eae2009-03-09 00:07:03 +00002572static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002573textiowrapper_repr(textio *self)
Benjamin Petersonc4c0eae2009-03-09 00:07:03 +00002574{
Antoine Pitroua4815ca2011-01-09 20:38:15 +00002575 PyObject *nameobj, *modeobj, *res, *s;
Serhiy Storchakaa5af6e12017-03-19 19:25:29 +02002576 int status;
Antoine Pitrou716c4442009-05-23 19:04:03 +00002577
2578 CHECK_INITIALIZED(self);
2579
Antoine Pitroua4815ca2011-01-09 20:38:15 +00002580 res = PyUnicode_FromString("<_io.TextIOWrapper");
2581 if (res == NULL)
2582 return NULL;
Benjamin Peterson10e76b62014-12-21 20:51:50 -06002583
Serhiy Storchakaa5af6e12017-03-19 19:25:29 +02002584 status = Py_ReprEnter((PyObject *)self);
2585 if (status != 0) {
2586 if (status > 0) {
2587 PyErr_Format(PyExc_RuntimeError,
2588 "reentrant call inside %s.__repr__",
2589 Py_TYPE(self)->tp_name);
2590 }
2591 goto error;
2592 }
Martin v. Löwis767046a2011-10-14 15:35:36 +02002593 nameobj = _PyObject_GetAttrId((PyObject *) self, &PyId_name);
Antoine Pitrou716c4442009-05-23 19:04:03 +00002594 if (nameobj == NULL) {
Benjamin Peterson10e76b62014-12-21 20:51:50 -06002595 if (PyErr_ExceptionMatches(PyExc_Exception))
Antoine Pitrou716c4442009-05-23 19:04:03 +00002596 PyErr_Clear();
2597 else
Antoine Pitroua4815ca2011-01-09 20:38:15 +00002598 goto error;
Antoine Pitrou716c4442009-05-23 19:04:03 +00002599 }
2600 else {
Antoine Pitroua4815ca2011-01-09 20:38:15 +00002601 s = PyUnicode_FromFormat(" name=%R", nameobj);
Antoine Pitrou716c4442009-05-23 19:04:03 +00002602 Py_DECREF(nameobj);
Antoine Pitroua4815ca2011-01-09 20:38:15 +00002603 if (s == NULL)
2604 goto error;
2605 PyUnicode_AppendAndDel(&res, s);
2606 if (res == NULL)
Serhiy Storchakaa5af6e12017-03-19 19:25:29 +02002607 goto error;
Antoine Pitrou716c4442009-05-23 19:04:03 +00002608 }
Martin v. Löwis767046a2011-10-14 15:35:36 +02002609 modeobj = _PyObject_GetAttrId((PyObject *) self, &PyId_mode);
Antoine Pitroua4815ca2011-01-09 20:38:15 +00002610 if (modeobj == NULL) {
Benjamin Peterson10e76b62014-12-21 20:51:50 -06002611 if (PyErr_ExceptionMatches(PyExc_Exception))
Antoine Pitroua4815ca2011-01-09 20:38:15 +00002612 PyErr_Clear();
2613 else
2614 goto error;
2615 }
2616 else {
2617 s = PyUnicode_FromFormat(" mode=%R", modeobj);
2618 Py_DECREF(modeobj);
2619 if (s == NULL)
2620 goto error;
2621 PyUnicode_AppendAndDel(&res, s);
2622 if (res == NULL)
Serhiy Storchakaa5af6e12017-03-19 19:25:29 +02002623 goto error;
Antoine Pitroua4815ca2011-01-09 20:38:15 +00002624 }
2625 s = PyUnicode_FromFormat("%U encoding=%R>",
2626 res, self->encoding);
2627 Py_DECREF(res);
Serhiy Storchakaa5af6e12017-03-19 19:25:29 +02002628 if (status == 0) {
2629 Py_ReprLeave((PyObject *)self);
2630 }
Antoine Pitroua4815ca2011-01-09 20:38:15 +00002631 return s;
Serhiy Storchakaa5af6e12017-03-19 19:25:29 +02002632
2633 error:
Antoine Pitroua4815ca2011-01-09 20:38:15 +00002634 Py_XDECREF(res);
Serhiy Storchakaa5af6e12017-03-19 19:25:29 +02002635 if (status == 0) {
2636 Py_ReprLeave((PyObject *)self);
2637 }
Antoine Pitroua4815ca2011-01-09 20:38:15 +00002638 return NULL;
Benjamin Petersonc4c0eae2009-03-09 00:07:03 +00002639}
2640
2641
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002642/* Inquiries */
2643
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03002644/*[clinic input]
2645_io.TextIOWrapper.fileno
2646[clinic start generated code]*/
2647
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002648static PyObject *
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03002649_io_TextIOWrapper_fileno_impl(textio *self)
2650/*[clinic end generated code: output=21490a4c3da13e6c input=c488ca83d0069f9b]*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002651{
Benjamin Peterson10e76b62014-12-21 20:51:50 -06002652 CHECK_ATTACHED(self);
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02002653 return _PyObject_CallMethodId(self->buffer, &PyId_fileno, NULL);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002654}
2655
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03002656/*[clinic input]
2657_io.TextIOWrapper.seekable
2658[clinic start generated code]*/
2659
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002660static PyObject *
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03002661_io_TextIOWrapper_seekable_impl(textio *self)
2662/*[clinic end generated code: output=ab223dbbcffc0f00 input=8b005ca06e1fca13]*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002663{
Benjamin Peterson10e76b62014-12-21 20:51:50 -06002664 CHECK_ATTACHED(self);
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02002665 return _PyObject_CallMethodId(self->buffer, &PyId_seekable, NULL);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002666}
2667
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03002668/*[clinic input]
2669_io.TextIOWrapper.readable
2670[clinic start generated code]*/
2671
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002672static PyObject *
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03002673_io_TextIOWrapper_readable_impl(textio *self)
2674/*[clinic end generated code: output=72ff7ba289a8a91b input=0704ea7e01b0d3eb]*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002675{
Benjamin Peterson10e76b62014-12-21 20:51:50 -06002676 CHECK_ATTACHED(self);
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02002677 return _PyObject_CallMethodId(self->buffer, &PyId_readable, NULL);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002678}
2679
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03002680/*[clinic input]
2681_io.TextIOWrapper.writable
2682[clinic start generated code]*/
2683
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002684static PyObject *
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03002685_io_TextIOWrapper_writable_impl(textio *self)
2686/*[clinic end generated code: output=a728c71790d03200 input=c41740bc9d8636e8]*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002687{
Benjamin Peterson10e76b62014-12-21 20:51:50 -06002688 CHECK_ATTACHED(self);
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02002689 return _PyObject_CallMethodId(self->buffer, &PyId_writable, NULL);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002690}
2691
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03002692/*[clinic input]
2693_io.TextIOWrapper.isatty
2694[clinic start generated code]*/
2695
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002696static PyObject *
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03002697_io_TextIOWrapper_isatty_impl(textio *self)
2698/*[clinic end generated code: output=12be1a35bace882e input=fb68d9f2c99bbfff]*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002699{
Benjamin Peterson10e76b62014-12-21 20:51:50 -06002700 CHECK_ATTACHED(self);
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02002701 return _PyObject_CallMethodId(self->buffer, &PyId_isatty, NULL);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002702}
2703
2704static PyObject *
Antoine Pitrou243757e2010-11-05 21:15:39 +00002705textiowrapper_getstate(textio *self, PyObject *args)
2706{
2707 PyErr_Format(PyExc_TypeError,
2708 "cannot serialize '%s' object", Py_TYPE(self)->tp_name);
2709 return NULL;
2710}
2711
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03002712/*[clinic input]
2713_io.TextIOWrapper.flush
2714[clinic start generated code]*/
2715
Antoine Pitrou243757e2010-11-05 21:15:39 +00002716static PyObject *
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03002717_io_TextIOWrapper_flush_impl(textio *self)
2718/*[clinic end generated code: output=59de9165f9c2e4d2 input=928c60590694ab85]*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002719{
Benjamin Peterson10e76b62014-12-21 20:51:50 -06002720 CHECK_ATTACHED(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002721 CHECK_CLOSED(self);
2722 self->telling = self->seekable;
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002723 if (_textiowrapper_writeflush(self) < 0)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002724 return NULL;
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02002725 return _PyObject_CallMethodId(self->buffer, &PyId_flush, NULL);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002726}
2727
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03002728/*[clinic input]
2729_io.TextIOWrapper.close
2730[clinic start generated code]*/
2731
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002732static PyObject *
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03002733_io_TextIOWrapper_close_impl(textio *self)
2734/*[clinic end generated code: output=056ccf8b4876e4f4 input=9c2114315eae1948]*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002735{
2736 PyObject *res;
Antoine Pitrou6be88762010-05-03 16:48:20 +00002737 int r;
Benjamin Peterson10e76b62014-12-21 20:51:50 -06002738 CHECK_ATTACHED(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002739
Antoine Pitrou6be88762010-05-03 16:48:20 +00002740 res = textiowrapper_closed_get(self, NULL);
2741 if (res == NULL)
2742 return NULL;
2743 r = PyObject_IsTrue(res);
2744 Py_DECREF(res);
2745 if (r < 0)
2746 return NULL;
Victor Stinnerf6c57832010-05-19 01:17:01 +00002747
Antoine Pitrou6be88762010-05-03 16:48:20 +00002748 if (r > 0) {
2749 Py_RETURN_NONE; /* stream already closed */
2750 }
2751 else {
Benjamin Peterson68623612012-12-20 11:53:11 -06002752 PyObject *exc = NULL, *val, *tb;
Antoine Pitrou796564c2013-07-30 19:59:21 +02002753 if (self->finalizing) {
Victor Stinner61bdb0d2016-12-09 15:39:28 +01002754 res = _PyObject_CallMethodIdObjArgs(self->buffer,
2755 &PyId__dealloc_warn,
2756 self, NULL);
Antoine Pitroue033e062010-10-29 10:38:18 +00002757 if (res)
2758 Py_DECREF(res);
2759 else
2760 PyErr_Clear();
2761 }
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02002762 res = _PyObject_CallMethodId((PyObject *)self, &PyId_flush, NULL);
Benjamin Peterson68623612012-12-20 11:53:11 -06002763 if (res == NULL)
2764 PyErr_Fetch(&exc, &val, &tb);
Antoine Pitrou6be88762010-05-03 16:48:20 +00002765 else
2766 Py_DECREF(res);
2767
Benjamin Peterson68623612012-12-20 11:53:11 -06002768 res = _PyObject_CallMethodId(self->buffer, &PyId_close, NULL);
2769 if (exc != NULL) {
Serhiy Storchakae2bd2a72014-10-08 22:31:52 +03002770 _PyErr_ChainExceptions(exc, val, tb);
2771 Py_CLEAR(res);
Benjamin Peterson68623612012-12-20 11:53:11 -06002772 }
2773 return res;
Antoine Pitrou6be88762010-05-03 16:48:20 +00002774 }
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002775}
2776
2777static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002778textiowrapper_iternext(textio *self)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002779{
2780 PyObject *line;
2781
Benjamin Peterson10e76b62014-12-21 20:51:50 -06002782 CHECK_ATTACHED(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002783
2784 self->telling = 0;
2785 if (Py_TYPE(self) == &PyTextIOWrapper_Type) {
2786 /* Skip method call overhead for speed */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002787 line = _textiowrapper_readline(self, -1);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002788 }
2789 else {
2790 line = PyObject_CallMethodObjArgs((PyObject *)self,
2791 _PyIO_str_readline, NULL);
2792 if (line && !PyUnicode_Check(line)) {
Serhiy Storchaka55fe1ae2017-04-16 10:46:38 +03002793 PyErr_Format(PyExc_OSError,
Serhiy Storchakab6a9c972016-04-17 09:39:28 +03002794 "readline() should have returned a str object, "
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002795 "not '%.200s'", Py_TYPE(line)->tp_name);
2796 Py_DECREF(line);
2797 return NULL;
2798 }
2799 }
2800
Martin v. Löwisd63a3b82011-09-28 07:41:54 +02002801 if (line == NULL || PyUnicode_READY(line) == -1)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002802 return NULL;
2803
Martin v. Löwisd63a3b82011-09-28 07:41:54 +02002804 if (PyUnicode_GET_LENGTH(line) == 0) {
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002805 /* Reached EOF or would have blocked */
2806 Py_DECREF(line);
2807 Py_CLEAR(self->snapshot);
2808 self->telling = self->seekable;
2809 return NULL;
2810 }
2811
2812 return line;
2813}
2814
2815static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002816textiowrapper_name_get(textio *self, void *context)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002817{
Benjamin Peterson10e76b62014-12-21 20:51:50 -06002818 CHECK_ATTACHED(self);
Martin v. Löwis767046a2011-10-14 15:35:36 +02002819 return _PyObject_GetAttrId(self->buffer, &PyId_name);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002820}
2821
2822static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002823textiowrapper_closed_get(textio *self, void *context)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002824{
Benjamin Peterson10e76b62014-12-21 20:51:50 -06002825 CHECK_ATTACHED(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002826 return PyObject_GetAttr(self->buffer, _PyIO_str_closed);
2827}
2828
2829static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002830textiowrapper_newlines_get(textio *self, void *context)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002831{
2832 PyObject *res;
Benjamin Peterson10e76b62014-12-21 20:51:50 -06002833 CHECK_ATTACHED(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002834 if (self->decoder == NULL)
2835 Py_RETURN_NONE;
2836 res = PyObject_GetAttr(self->decoder, _PyIO_str_newlines);
2837 if (res == NULL) {
Benjamin Peterson2cfca792009-06-06 20:46:48 +00002838 if (PyErr_ExceptionMatches(PyExc_AttributeError)) {
2839 PyErr_Clear();
2840 Py_RETURN_NONE;
2841 }
2842 else {
2843 return NULL;
2844 }
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002845 }
2846 return res;
2847}
2848
2849static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002850textiowrapper_errors_get(textio *self, void *context)
Benjamin Peterson0926ad12009-06-06 18:02:12 +00002851{
2852 CHECK_INITIALIZED(self);
2853 return PyUnicode_FromString(PyBytes_AS_STRING(self->errors));
2854}
2855
2856static PyObject *
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002857textiowrapper_chunk_size_get(textio *self, void *context)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002858{
Benjamin Peterson10e76b62014-12-21 20:51:50 -06002859 CHECK_ATTACHED(self);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002860 return PyLong_FromSsize_t(self->chunk_size);
2861}
2862
2863static int
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002864textiowrapper_chunk_size_set(textio *self, PyObject *arg, void *context)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002865{
2866 Py_ssize_t n;
Benjamin Peterson10e76b62014-12-21 20:51:50 -06002867 CHECK_ATTACHED_INT(self);
Antoine Pitroucb4ae812011-07-13 21:07:49 +02002868 n = PyNumber_AsSsize_t(arg, PyExc_ValueError);
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002869 if (n == -1 && PyErr_Occurred())
2870 return -1;
2871 if (n <= 0) {
2872 PyErr_SetString(PyExc_ValueError,
2873 "a strictly positive integer is required");
2874 return -1;
2875 }
2876 self->chunk_size = n;
2877 return 0;
2878}
2879
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03002880#include "clinic/textio.c.h"
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002881
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03002882static PyMethodDef incrementalnewlinedecoder_methods[] = {
2883 _IO_INCREMENTALNEWLINEDECODER_DECODE_METHODDEF
2884 _IO_INCREMENTALNEWLINEDECODER_GETSTATE_METHODDEF
2885 _IO_INCREMENTALNEWLINEDECODER_SETSTATE_METHODDEF
2886 _IO_INCREMENTALNEWLINEDECODER_RESET_METHODDEF
2887 {NULL}
2888};
2889
2890static PyGetSetDef incrementalnewlinedecoder_getset[] = {
2891 {"newlines", (getter)incrementalnewlinedecoder_newlines_get, NULL, NULL},
2892 {NULL}
2893};
2894
2895PyTypeObject PyIncrementalNewlineDecoder_Type = {
2896 PyVarObject_HEAD_INIT(NULL, 0)
2897 "_io.IncrementalNewlineDecoder", /*tp_name*/
2898 sizeof(nldecoder_object), /*tp_basicsize*/
2899 0, /*tp_itemsize*/
2900 (destructor)incrementalnewlinedecoder_dealloc, /*tp_dealloc*/
2901 0, /*tp_print*/
2902 0, /*tp_getattr*/
2903 0, /*tp_setattr*/
2904 0, /*tp_compare */
2905 0, /*tp_repr*/
2906 0, /*tp_as_number*/
2907 0, /*tp_as_sequence*/
2908 0, /*tp_as_mapping*/
2909 0, /*tp_hash */
2910 0, /*tp_call*/
2911 0, /*tp_str*/
2912 0, /*tp_getattro*/
2913 0, /*tp_setattro*/
2914 0, /*tp_as_buffer*/
2915 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /*tp_flags*/
2916 _io_IncrementalNewlineDecoder___init____doc__, /* tp_doc */
2917 0, /* tp_traverse */
2918 0, /* tp_clear */
2919 0, /* tp_richcompare */
2920 0, /*tp_weaklistoffset*/
2921 0, /* tp_iter */
2922 0, /* tp_iternext */
2923 incrementalnewlinedecoder_methods, /* tp_methods */
2924 0, /* tp_members */
2925 incrementalnewlinedecoder_getset, /* tp_getset */
2926 0, /* tp_base */
2927 0, /* tp_dict */
2928 0, /* tp_descr_get */
2929 0, /* tp_descr_set */
2930 0, /* tp_dictoffset */
2931 _io_IncrementalNewlineDecoder___init__, /* tp_init */
2932 0, /* tp_alloc */
2933 PyType_GenericNew, /* tp_new */
2934};
2935
2936
2937static PyMethodDef textiowrapper_methods[] = {
2938 _IO_TEXTIOWRAPPER_DETACH_METHODDEF
Antoine Pitrou3c2817b2017-06-03 12:32:28 +02002939 _IO_TEXTIOWRAPPER_RECONFIGURE_METHODDEF
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03002940 _IO_TEXTIOWRAPPER_WRITE_METHODDEF
2941 _IO_TEXTIOWRAPPER_READ_METHODDEF
2942 _IO_TEXTIOWRAPPER_READLINE_METHODDEF
2943 _IO_TEXTIOWRAPPER_FLUSH_METHODDEF
2944 _IO_TEXTIOWRAPPER_CLOSE_METHODDEF
2945
2946 _IO_TEXTIOWRAPPER_FILENO_METHODDEF
2947 _IO_TEXTIOWRAPPER_SEEKABLE_METHODDEF
2948 _IO_TEXTIOWRAPPER_READABLE_METHODDEF
2949 _IO_TEXTIOWRAPPER_WRITABLE_METHODDEF
2950 _IO_TEXTIOWRAPPER_ISATTY_METHODDEF
Antoine Pitrou243757e2010-11-05 21:15:39 +00002951 {"__getstate__", (PyCFunction)textiowrapper_getstate, METH_NOARGS},
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002952
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03002953 _IO_TEXTIOWRAPPER_SEEK_METHODDEF
2954 _IO_TEXTIOWRAPPER_TELL_METHODDEF
2955 _IO_TEXTIOWRAPPER_TRUNCATE_METHODDEF
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002956 {NULL, NULL}
2957};
2958
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002959static PyMemberDef textiowrapper_members[] = {
2960 {"encoding", T_OBJECT, offsetof(textio, encoding), READONLY},
2961 {"buffer", T_OBJECT, offsetof(textio, buffer), READONLY},
2962 {"line_buffering", T_BOOL, offsetof(textio, line_buffering), READONLY},
Antoine Pitrou3c2817b2017-06-03 12:32:28 +02002963 {"write_through", T_BOOL, offsetof(textio, write_through), READONLY},
Antoine Pitrou796564c2013-07-30 19:59:21 +02002964 {"_finalizing", T_BOOL, offsetof(textio, finalizing), 0},
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002965 {NULL}
2966};
2967
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002968static PyGetSetDef textiowrapper_getset[] = {
2969 {"name", (getter)textiowrapper_name_get, NULL, NULL},
2970 {"closed", (getter)textiowrapper_closed_get, NULL, NULL},
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002971/* {"mode", (getter)TextIOWrapper_mode_get, NULL, NULL},
2972*/
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002973 {"newlines", (getter)textiowrapper_newlines_get, NULL, NULL},
2974 {"errors", (getter)textiowrapper_errors_get, NULL, NULL},
2975 {"_CHUNK_SIZE", (getter)textiowrapper_chunk_size_get,
2976 (setter)textiowrapper_chunk_size_set, NULL},
Benjamin Peterson1fea3212009-04-19 03:15:20 +00002977 {NULL}
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002978};
2979
2980PyTypeObject PyTextIOWrapper_Type = {
2981 PyVarObject_HEAD_INIT(NULL, 0)
2982 "_io.TextIOWrapper", /*tp_name*/
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002983 sizeof(textio), /*tp_basicsize*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002984 0, /*tp_itemsize*/
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002985 (destructor)textiowrapper_dealloc, /*tp_dealloc*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002986 0, /*tp_print*/
2987 0, /*tp_getattr*/
Benjamin Petersonc4c0eae2009-03-09 00:07:03 +00002988 0, /*tps_etattr*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002989 0, /*tp_compare */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00002990 (reprfunc)textiowrapper_repr,/*tp_repr*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00002991 0, /*tp_as_number*/
2992 0, /*tp_as_sequence*/
2993 0, /*tp_as_mapping*/
2994 0, /*tp_hash */
2995 0, /*tp_call*/
2996 0, /*tp_str*/
2997 0, /*tp_getattro*/
2998 0, /*tp_setattro*/
2999 0, /*tp_as_buffer*/
3000 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE
Antoine Pitrou796564c2013-07-30 19:59:21 +02003001 | Py_TPFLAGS_HAVE_GC | Py_TPFLAGS_HAVE_FINALIZE, /*tp_flags*/
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03003002 _io_TextIOWrapper___init____doc__, /* tp_doc */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00003003 (traverseproc)textiowrapper_traverse, /* tp_traverse */
3004 (inquiry)textiowrapper_clear, /* tp_clear */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00003005 0, /* tp_richcompare */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00003006 offsetof(textio, weakreflist), /*tp_weaklistoffset*/
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00003007 0, /* tp_iter */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00003008 (iternextfunc)textiowrapper_iternext, /* tp_iternext */
3009 textiowrapper_methods, /* tp_methods */
3010 textiowrapper_members, /* tp_members */
3011 textiowrapper_getset, /* tp_getset */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00003012 0, /* tp_base */
3013 0, /* tp_dict */
3014 0, /* tp_descr_get */
3015 0, /* tp_descr_set */
Benjamin Peterson680bf1a2009-06-12 02:07:12 +00003016 offsetof(textio, dict), /*tp_dictoffset*/
Serhiy Storchakaf24131f2015-04-16 11:19:43 +03003017 _io_TextIOWrapper___init__, /* tp_init */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00003018 0, /* tp_alloc */
3019 PyType_GenericNew, /* tp_new */
Antoine Pitrou796564c2013-07-30 19:59:21 +02003020 0, /* tp_free */
3021 0, /* tp_is_gc */
3022 0, /* tp_bases */
3023 0, /* tp_mro */
3024 0, /* tp_cache */
3025 0, /* tp_subclasses */
3026 0, /* tp_weaklist */
3027 0, /* tp_del */
3028 0, /* tp_version_tag */
3029 0, /* tp_finalize */
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00003030};