Branch data Line data Source code
1 : : /*
2 : : An implementation of the I/O abstract base classes hierarchy
3 : : as defined by PEP 3116 - "New I/O"
4 : :
5 : : Classes defined here: IOBase, RawIOBase.
6 : :
7 : : Written by Amaury Forgeot d'Arc and Antoine Pitrou
8 : : */
9 : :
10 : :
11 : : #define PY_SSIZE_T_CLEAN
12 : : #include "Python.h"
13 : : #include "pycore_long.h" // _PyLong_GetOne()
14 : : #include "pycore_object.h"
15 : : #include <stddef.h> // offsetof()
16 : : #include "_iomodule.h"
17 : :
18 : : /*[clinic input]
19 : : module _io
20 : : class _io._IOBase "PyObject *" "&PyIOBase_Type"
21 : : class _io._RawIOBase "PyObject *" "&PyRawIOBase_Type"
22 : : [clinic start generated code]*/
23 : : /*[clinic end generated code: output=da39a3ee5e6b4b0d input=d29a4d076c2b211c]*/
24 : :
25 : : /*
26 : : * IOBase class, an abstract class
27 : : */
28 : :
29 : : typedef struct {
30 : : PyObject_HEAD
31 : :
32 : : PyObject *dict;
33 : : PyObject *weakreflist;
34 : : } iobase;
35 : :
36 : : PyDoc_STRVAR(iobase_doc,
37 : : "The abstract base class for all I/O classes.\n"
38 : : "\n"
39 : : "This class provides dummy implementations for many methods that\n"
40 : : "derived classes can override selectively; the default implementations\n"
41 : : "represent a file that cannot be read, written or seeked.\n"
42 : : "\n"
43 : : "Even though IOBase does not declare read, readinto, or write because\n"
44 : : "their signatures will vary, implementations and clients should\n"
45 : : "consider those methods part of the interface. Also, implementations\n"
46 : : "may raise UnsupportedOperation when operations they do not support are\n"
47 : : "called.\n"
48 : : "\n"
49 : : "The basic type used for binary data read from or written to a file is\n"
50 : : "bytes. Other bytes-like objects are accepted as method arguments too.\n"
51 : : "In some cases (such as readinto), a writable object is required. Text\n"
52 : : "I/O classes work with str data.\n"
53 : : "\n"
54 : : "Note that calling any method (except additional calls to close(),\n"
55 : : "which are ignored) on a closed stream should raise a ValueError.\n"
56 : : "\n"
57 : : "IOBase (and its subclasses) support the iterator protocol, meaning\n"
58 : : "that an IOBase object can be iterated over yielding the lines in a\n"
59 : : "stream.\n"
60 : : "\n"
61 : : "IOBase also supports the :keyword:`with` statement. In this example,\n"
62 : : "fp is closed after the suite of the with statement is complete:\n"
63 : : "\n"
64 : : "with open('spam.txt', 'r') as fp:\n"
65 : : " fp.write('Spam and eggs!')\n");
66 : :
67 : : /* Use this macro whenever you want to check the internal `closed` status
68 : : of the IOBase object rather than the virtual `closed` attribute as returned
69 : : by whatever subclass. */
70 : :
71 : :
72 : : /* Internal methods */
73 : : static PyObject *
74 : 0 : iobase_unsupported(const char *message)
75 : : {
76 : 0 : _PyIO_State *state = IO_STATE();
77 [ # # ]: 0 : if (state != NULL)
78 : 0 : PyErr_SetString(state->unsupported_operation, message);
79 : 0 : return NULL;
80 : : }
81 : :
82 : : /* Positioning */
83 : :
84 : : PyDoc_STRVAR(iobase_seek_doc,
85 : : "Change stream position.\n"
86 : : "\n"
87 : : "Change the stream position to the given byte offset. The offset is\n"
88 : : "interpreted relative to the position indicated by whence. Values\n"
89 : : "for whence are:\n"
90 : : "\n"
91 : : "* 0 -- start of stream (the default); offset should be zero or positive\n"
92 : : "* 1 -- current stream position; offset may be negative\n"
93 : : "* 2 -- end of stream; offset is usually negative\n"
94 : : "\n"
95 : : "Return the new absolute position.");
96 : :
97 : : static PyObject *
98 : 0 : iobase_seek(PyObject *self, PyObject *args)
99 : : {
100 : 0 : return iobase_unsupported("seek");
101 : : }
102 : :
103 : : /*[clinic input]
104 : : _io._IOBase.tell
105 : :
106 : : Return current stream position.
107 : : [clinic start generated code]*/
108 : :
109 : : static PyObject *
110 : 0 : _io__IOBase_tell_impl(PyObject *self)
111 : : /*[clinic end generated code: output=89a1c0807935abe2 input=04e615fec128801f]*/
112 : : {
113 : 0 : return _PyObject_CallMethod(self, &_Py_ID(seek), "ii", 0, 1);
114 : : }
115 : :
116 : : PyDoc_STRVAR(iobase_truncate_doc,
117 : : "Truncate file to size bytes.\n"
118 : : "\n"
119 : : "File pointer is left unchanged. Size defaults to the current IO\n"
120 : : "position as reported by tell(). Returns the new size.");
121 : :
122 : : static PyObject *
123 : 0 : iobase_truncate(PyObject *self, PyObject *args)
124 : : {
125 : 0 : return iobase_unsupported("truncate");
126 : : }
127 : :
128 : : static int
129 : 4946 : iobase_is_closed(PyObject *self)
130 : : {
131 : : PyObject *res;
132 : : int ret;
133 : : /* This gets the derived attribute, which is *not* __IOBase_closed
134 : : in most cases! */
135 : 4946 : ret = _PyObject_LookupAttr(self, &_Py_ID(__IOBase_closed), &res);
136 : 4946 : Py_XDECREF(res);
137 : 4946 : return ret;
138 : : }
139 : :
140 : : /* Flush and close methods */
141 : :
142 : : /*[clinic input]
143 : : _io._IOBase.flush
144 : :
145 : : Flush write buffers, if applicable.
146 : :
147 : : This is not implemented for read-only and non-blocking streams.
148 : : [clinic start generated code]*/
149 : :
150 : : static PyObject *
151 : 3446 : _io__IOBase_flush_impl(PyObject *self)
152 : : /*[clinic end generated code: output=7cef4b4d54656a3b input=773be121abe270aa]*/
153 : : {
154 : : /* XXX Should this return the number of bytes written??? */
155 : 3446 : int closed = iobase_is_closed(self);
156 : :
157 [ + - ]: 3446 : if (!closed) {
158 : 3446 : Py_RETURN_NONE;
159 : : }
160 [ # # ]: 0 : if (closed > 0) {
161 : 0 : PyErr_SetString(PyExc_ValueError, "I/O operation on closed file.");
162 : : }
163 : 0 : return NULL;
164 : : }
165 : :
166 : : static PyObject *
167 : 0 : iobase_closed_get(PyObject *self, void *context)
168 : : {
169 : 0 : int closed = iobase_is_closed(self);
170 [ # # ]: 0 : if (closed < 0) {
171 : 0 : return NULL;
172 : : }
173 : 0 : return PyBool_FromLong(closed);
174 : : }
175 : :
176 : : static int
177 : 148545 : iobase_check_closed(PyObject *self)
178 : : {
179 : : PyObject *res;
180 : : int closed;
181 : : /* This gets the derived attribute, which is *not* __IOBase_closed
182 : : in most cases! */
183 : 148545 : closed = _PyObject_LookupAttr(self, &_Py_ID(closed), &res);
184 [ + - ]: 148545 : if (closed > 0) {
185 : 148545 : closed = PyObject_IsTrue(res);
186 : 148545 : Py_DECREF(res);
187 [ - + ]: 148545 : if (closed > 0) {
188 : 0 : PyErr_SetString(PyExc_ValueError, "I/O operation on closed file.");
189 : 0 : return -1;
190 : : }
191 : : }
192 : 148545 : return closed;
193 : : }
194 : :
195 : : PyObject *
196 : 0 : _PyIOBase_check_closed(PyObject *self, PyObject *args)
197 : : {
198 [ # # ]: 0 : if (iobase_check_closed(self)) {
199 : 0 : return NULL;
200 : : }
201 [ # # ]: 0 : if (args == Py_True) {
202 : 0 : return Py_None;
203 : : }
204 : 0 : Py_RETURN_NONE;
205 : : }
206 : :
207 : : /* XXX: IOBase thinks it has to maintain its own internal state in
208 : : `__IOBase_closed` and call flush() by itself, but it is redundant with
209 : : whatever behaviour a non-trivial derived class will implement. */
210 : :
211 : : /*[clinic input]
212 : : _io._IOBase.close
213 : :
214 : : Flush and close the IO object.
215 : :
216 : : This method has no effect if the file is already closed.
217 : : [clinic start generated code]*/
218 : :
219 : : static PyObject *
220 : 1500 : _io__IOBase_close_impl(PyObject *self)
221 : : /*[clinic end generated code: output=63c6a6f57d783d6d input=f4494d5c31dbc6b7]*/
222 : : {
223 : 1500 : int rc, closed = iobase_is_closed(self);
224 : :
225 [ - + ]: 1500 : if (closed < 0) {
226 : 0 : return NULL;
227 : : }
228 [ - + ]: 1500 : if (closed) {
229 : 0 : Py_RETURN_NONE;
230 : : }
231 : :
232 : 1500 : PyObject *res = PyObject_CallMethodNoArgs(self, &_Py_ID(flush));
233 : :
234 : 1500 : PyObject *exc = PyErr_GetRaisedException();
235 : 1500 : rc = PyObject_SetAttr(self, &_Py_ID(__IOBase_closed), Py_True);
236 : 1500 : _PyErr_ChainExceptions1(exc);
237 [ - + ]: 1500 : if (rc < 0) {
238 [ # # ]: 0 : Py_CLEAR(res);
239 : : }
240 : :
241 [ - + ]: 1500 : if (res == NULL)
242 : 0 : return NULL;
243 : :
244 : 1500 : Py_DECREF(res);
245 : 1500 : Py_RETURN_NONE;
246 : : }
247 : :
248 : : /* Finalization and garbage collection support */
249 : :
250 : : static void
251 : 3755 : iobase_finalize(PyObject *self)
252 : : {
253 : : PyObject *res;
254 : : int closed;
255 : :
256 : : /* Save the current exception, if any. */
257 : 3755 : PyObject *exc = PyErr_GetRaisedException();
258 : :
259 : : /* If `closed` doesn't exist or can't be evaluated as bool, then the
260 : : object is probably in an unusable state, so ignore. */
261 [ - + ]: 3755 : if (_PyObject_LookupAttr(self, &_Py_ID(closed), &res) <= 0) {
262 : 0 : PyErr_Clear();
263 : 0 : closed = -1;
264 : : }
265 : : else {
266 : 3755 : closed = PyObject_IsTrue(res);
267 : 3755 : Py_DECREF(res);
268 [ - + ]: 3755 : if (closed == -1)
269 : 0 : PyErr_Clear();
270 : : }
271 [ + + ]: 3755 : if (closed == 0) {
272 : : /* Signal close() that it was called as part of the object
273 : : finalization process. */
274 [ - + ]: 76 : if (PyObject_SetAttr(self, &_Py_ID(_finalizing), Py_True))
275 : 0 : PyErr_Clear();
276 : 76 : res = PyObject_CallMethodNoArgs((PyObject *)self, &_Py_ID(close));
277 : : /* Silencing I/O errors is bad, but printing spurious tracebacks is
278 : : equally as bad, and potentially more frequent (because of
279 : : shutdown issues). */
280 [ - + ]: 76 : if (res == NULL) {
281 : : #ifndef Py_DEBUG
282 [ # # ]: 0 : if (_Py_GetConfig()->dev_mode) {
283 : 0 : PyErr_WriteUnraisable(self);
284 : : }
285 : : else {
286 : 0 : PyErr_Clear();
287 : : }
288 : : #else
289 : : PyErr_WriteUnraisable(self);
290 : : #endif
291 : : }
292 : : else {
293 : 76 : Py_DECREF(res);
294 : : }
295 : : }
296 : :
297 : : /* Restore the saved exception. */
298 : 3755 : PyErr_SetRaisedException(exc);
299 : 3755 : }
300 : :
301 : : int
302 : 3754 : _PyIOBase_finalize(PyObject *self)
303 : : {
304 : : int is_zombie;
305 : :
306 : : /* If _PyIOBase_finalize() is called from a destructor, we need to
307 : : resurrect the object as calling close() can invoke arbitrary code. */
308 : 3754 : is_zombie = (Py_REFCNT(self) == 0);
309 [ + - ]: 3754 : if (is_zombie)
310 : 3754 : return PyObject_CallFinalizerFromDealloc(self);
311 : : else {
312 : 0 : PyObject_CallFinalizer(self);
313 : 0 : return 0;
314 : : }
315 : : }
316 : :
317 : : static int
318 : 0 : iobase_traverse(iobase *self, visitproc visit, void *arg)
319 : : {
320 [ # # # # ]: 0 : Py_VISIT(self->dict);
321 : 0 : return 0;
322 : : }
323 : :
324 : : static int
325 : 0 : iobase_clear(iobase *self)
326 : : {
327 [ # # ]: 0 : Py_CLEAR(self->dict);
328 : 0 : return 0;
329 : : }
330 : :
331 : : /* Destructor */
332 : :
333 : : static void
334 : 0 : iobase_dealloc(iobase *self)
335 : : {
336 : : /* NOTE: since IOBaseObject has its own dict, Python-defined attributes
337 : : are still available here for close() to use.
338 : : However, if the derived class declares a __slots__, those slots are
339 : : already gone.
340 : : */
341 [ # # ]: 0 : if (_PyIOBase_finalize((PyObject *) self) < 0) {
342 : : /* When called from a heap type's dealloc, the type will be
343 : : decref'ed on return (see e.g. subtype_dealloc in typeobject.c). */
344 [ # # ]: 0 : if (_PyType_HasFeature(Py_TYPE(self), Py_TPFLAGS_HEAPTYPE)) {
345 : 0 : Py_INCREF(Py_TYPE(self));
346 : : }
347 : 0 : return;
348 : : }
349 : 0 : _PyObject_GC_UNTRACK(self);
350 [ # # ]: 0 : if (self->weakreflist != NULL)
351 : 0 : PyObject_ClearWeakRefs((PyObject *) self);
352 [ # # ]: 0 : Py_CLEAR(self->dict);
353 : 0 : Py_TYPE(self)->tp_free((PyObject *) self);
354 : : }
355 : :
356 : : /* Inquiry methods */
357 : :
358 : : /*[clinic input]
359 : : _io._IOBase.seekable
360 : :
361 : : Return whether object supports random access.
362 : :
363 : : If False, seek(), tell() and truncate() will raise OSError.
364 : : This method may need to do a test seek().
365 : : [clinic start generated code]*/
366 : :
367 : : static PyObject *
368 : 0 : _io__IOBase_seekable_impl(PyObject *self)
369 : : /*[clinic end generated code: output=4c24c67f5f32a43d input=b976622f7fdf3063]*/
370 : : {
371 : 0 : Py_RETURN_FALSE;
372 : : }
373 : :
374 : : PyObject *
375 : 89 : _PyIOBase_check_seekable(PyObject *self, PyObject *args)
376 : : {
377 : 89 : PyObject *res = PyObject_CallMethodNoArgs(self, &_Py_ID(seekable));
378 [ - + ]: 89 : if (res == NULL)
379 : 0 : return NULL;
380 [ - + ]: 89 : if (res != Py_True) {
381 [ # # ]: 0 : Py_CLEAR(res);
382 : 0 : iobase_unsupported("File or stream is not seekable.");
383 : 0 : return NULL;
384 : : }
385 [ + - ]: 89 : if (args == Py_True) {
386 : 89 : Py_DECREF(res);
387 : : }
388 : 89 : return res;
389 : : }
390 : :
391 : : /*[clinic input]
392 : : _io._IOBase.readable
393 : :
394 : : Return whether object was opened for reading.
395 : :
396 : : If False, read() will raise OSError.
397 : : [clinic start generated code]*/
398 : :
399 : : static PyObject *
400 : 74 : _io__IOBase_readable_impl(PyObject *self)
401 : : /*[clinic end generated code: output=e48089250686388b input=285b3b866a0ec35f]*/
402 : : {
403 : 74 : Py_RETURN_FALSE;
404 : : }
405 : :
406 : : /* May be called with any object */
407 : : PyObject *
408 : 1267 : _PyIOBase_check_readable(PyObject *self, PyObject *args)
409 : : {
410 : 1267 : PyObject *res = PyObject_CallMethodNoArgs(self, &_Py_ID(readable));
411 [ - + ]: 1267 : if (res == NULL)
412 : 0 : return NULL;
413 [ - + ]: 1267 : if (res != Py_True) {
414 [ # # ]: 0 : Py_CLEAR(res);
415 : 0 : iobase_unsupported("File or stream is not readable.");
416 : 0 : return NULL;
417 : : }
418 [ + - ]: 1267 : if (args == Py_True) {
419 : 1267 : Py_DECREF(res);
420 : : }
421 : 1267 : return res;
422 : : }
423 : :
424 : : /*[clinic input]
425 : : _io._IOBase.writable
426 : :
427 : : Return whether object was opened for writing.
428 : :
429 : : If False, write() will raise OSError.
430 : : [clinic start generated code]*/
431 : :
432 : : static PyObject *
433 : 679 : _io__IOBase_writable_impl(PyObject *self)
434 : : /*[clinic end generated code: output=406001d0985be14f input=9dcac18a013a05b5]*/
435 : : {
436 : 679 : Py_RETURN_FALSE;
437 : : }
438 : :
439 : : /* May be called with any object */
440 : : PyObject *
441 : 74 : _PyIOBase_check_writable(PyObject *self, PyObject *args)
442 : : {
443 : 74 : PyObject *res = PyObject_CallMethodNoArgs(self, &_Py_ID(writable));
444 [ - + ]: 74 : if (res == NULL)
445 : 0 : return NULL;
446 [ - + ]: 74 : if (res != Py_True) {
447 [ # # ]: 0 : Py_CLEAR(res);
448 : 0 : iobase_unsupported("File or stream is not writable.");
449 : 0 : return NULL;
450 : : }
451 [ + - ]: 74 : if (args == Py_True) {
452 : 74 : Py_DECREF(res);
453 : : }
454 : 74 : return res;
455 : : }
456 : :
457 : : /* Context manager */
458 : :
459 : : static PyObject *
460 : 1424 : iobase_enter(PyObject *self, PyObject *args)
461 : : {
462 [ - + ]: 1424 : if (iobase_check_closed(self))
463 : 0 : return NULL;
464 : :
465 : 1424 : return Py_NewRef(self);
466 : : }
467 : :
468 : : static PyObject *
469 : 1424 : iobase_exit(PyObject *self, PyObject *args)
470 : : {
471 : 1424 : return PyObject_CallMethodNoArgs(self, &_Py_ID(close));
472 : : }
473 : :
474 : : /* Lower-level APIs */
475 : :
476 : : /* XXX Should these be present even if unimplemented? */
477 : :
478 : : /*[clinic input]
479 : : _io._IOBase.fileno
480 : :
481 : : Returns underlying file descriptor if one exists.
482 : :
483 : : OSError is raised if the IO object does not use a file descriptor.
484 : : [clinic start generated code]*/
485 : :
486 : : static PyObject *
487 : 0 : _io__IOBase_fileno_impl(PyObject *self)
488 : : /*[clinic end generated code: output=7cc0973f0f5f3b73 input=4e37028947dc1cc8]*/
489 : : {
490 : 0 : return iobase_unsupported("fileno");
491 : : }
492 : :
493 : : /*[clinic input]
494 : : _io._IOBase.isatty
495 : :
496 : : Return whether this is an 'interactive' stream.
497 : :
498 : : Return False if it can't be determined.
499 : : [clinic start generated code]*/
500 : :
501 : : static PyObject *
502 : 0 : _io__IOBase_isatty_impl(PyObject *self)
503 : : /*[clinic end generated code: output=60cab77cede41cdd input=9ef76530d368458b]*/
504 : : {
505 [ # # ]: 0 : if (iobase_check_closed(self))
506 : 0 : return NULL;
507 : 0 : Py_RETURN_FALSE;
508 : : }
509 : :
510 : : /* Readline(s) and writelines */
511 : :
512 : : /*[clinic input]
513 : : _io._IOBase.readline
514 : : size as limit: Py_ssize_t(accept={int, NoneType}) = -1
515 : : /
516 : :
517 : : Read and return a line from the stream.
518 : :
519 : : If size is specified, at most size bytes will be read.
520 : :
521 : : The line terminator is always b'\n' for binary files; for text
522 : : files, the newlines argument to open can be used to select the line
523 : : terminator(s) recognized.
524 : : [clinic start generated code]*/
525 : :
526 : : static PyObject *
527 : 0 : _io__IOBase_readline_impl(PyObject *self, Py_ssize_t limit)
528 : : /*[clinic end generated code: output=4479f79b58187840 input=d0c596794e877bff]*/
529 : : {
530 : : /* For backwards compatibility, a (slowish) readline(). */
531 : :
532 : : PyObject *peek, *buffer, *result;
533 : 0 : Py_ssize_t old_size = -1;
534 : :
535 [ # # ]: 0 : if (_PyObject_LookupAttr(self, &_Py_ID(peek), &peek) < 0) {
536 : 0 : return NULL;
537 : : }
538 : :
539 : 0 : buffer = PyByteArray_FromStringAndSize(NULL, 0);
540 [ # # ]: 0 : if (buffer == NULL) {
541 : 0 : Py_XDECREF(peek);
542 : 0 : return NULL;
543 : : }
544 : :
545 [ # # # # ]: 0 : while (limit < 0 || PyByteArray_GET_SIZE(buffer) < limit) {
546 : 0 : Py_ssize_t nreadahead = 1;
547 : : PyObject *b;
548 : :
549 [ # # ]: 0 : if (peek != NULL) {
550 : 0 : PyObject *readahead = PyObject_CallOneArg(peek, _PyLong_GetOne());
551 [ # # ]: 0 : if (readahead == NULL) {
552 : : /* NOTE: PyErr_SetFromErrno() calls PyErr_CheckSignals()
553 : : when EINTR occurs so we needn't do it ourselves. */
554 [ # # ]: 0 : if (_PyIO_trap_eintr()) {
555 : 0 : continue;
556 : : }
557 : 0 : goto fail;
558 : : }
559 [ # # ]: 0 : if (!PyBytes_Check(readahead)) {
560 : 0 : PyErr_Format(PyExc_OSError,
561 : : "peek() should have returned a bytes object, "
562 : 0 : "not '%.200s'", Py_TYPE(readahead)->tp_name);
563 : 0 : Py_DECREF(readahead);
564 : 0 : goto fail;
565 : : }
566 [ # # ]: 0 : if (PyBytes_GET_SIZE(readahead) > 0) {
567 : 0 : Py_ssize_t n = 0;
568 : 0 : const char *buf = PyBytes_AS_STRING(readahead);
569 [ # # ]: 0 : if (limit >= 0) {
570 : : do {
571 [ # # # # ]: 0 : if (n >= PyBytes_GET_SIZE(readahead) || n >= limit)
572 : : break;
573 [ # # ]: 0 : if (buf[n++] == '\n')
574 : 0 : break;
575 : : } while (1);
576 : : }
577 : : else {
578 : : do {
579 [ # # ]: 0 : if (n >= PyBytes_GET_SIZE(readahead))
580 : 0 : break;
581 [ # # ]: 0 : if (buf[n++] == '\n')
582 : 0 : break;
583 : : } while (1);
584 : : }
585 : 0 : nreadahead = n;
586 : : }
587 : 0 : Py_DECREF(readahead);
588 : : }
589 : :
590 : 0 : b = _PyObject_CallMethod(self, &_Py_ID(read), "n", nreadahead);
591 [ # # ]: 0 : if (b == NULL) {
592 : : /* NOTE: PyErr_SetFromErrno() calls PyErr_CheckSignals()
593 : : when EINTR occurs so we needn't do it ourselves. */
594 [ # # ]: 0 : if (_PyIO_trap_eintr()) {
595 : 0 : continue;
596 : : }
597 : 0 : goto fail;
598 : : }
599 [ # # ]: 0 : if (!PyBytes_Check(b)) {
600 : 0 : PyErr_Format(PyExc_OSError,
601 : : "read() should have returned a bytes object, "
602 : 0 : "not '%.200s'", Py_TYPE(b)->tp_name);
603 : 0 : Py_DECREF(b);
604 : 0 : goto fail;
605 : : }
606 [ # # ]: 0 : if (PyBytes_GET_SIZE(b) == 0) {
607 : 0 : Py_DECREF(b);
608 : 0 : break;
609 : : }
610 : :
611 : 0 : old_size = PyByteArray_GET_SIZE(buffer);
612 [ # # ]: 0 : if (PyByteArray_Resize(buffer, old_size + PyBytes_GET_SIZE(b)) < 0) {
613 : 0 : Py_DECREF(b);
614 : 0 : goto fail;
615 : : }
616 : 0 : memcpy(PyByteArray_AS_STRING(buffer) + old_size,
617 : 0 : PyBytes_AS_STRING(b), PyBytes_GET_SIZE(b));
618 : :
619 : 0 : Py_DECREF(b);
620 : :
621 [ # # ]: 0 : if (PyByteArray_AS_STRING(buffer)[PyByteArray_GET_SIZE(buffer) - 1] == '\n')
622 : 0 : break;
623 : : }
624 : :
625 : 0 : result = PyBytes_FromStringAndSize(PyByteArray_AS_STRING(buffer),
626 : : PyByteArray_GET_SIZE(buffer));
627 : 0 : Py_XDECREF(peek);
628 : 0 : Py_DECREF(buffer);
629 : 0 : return result;
630 : 0 : fail:
631 : 0 : Py_XDECREF(peek);
632 : 0 : Py_DECREF(buffer);
633 : 0 : return NULL;
634 : : }
635 : :
636 : : static PyObject *
637 : 629 : iobase_iter(PyObject *self)
638 : : {
639 [ - + ]: 629 : if (iobase_check_closed(self))
640 : 0 : return NULL;
641 : :
642 : 629 : return Py_NewRef(self);
643 : : }
644 : :
645 : : static PyObject *
646 : 0 : iobase_iternext(PyObject *self)
647 : : {
648 : 0 : PyObject *line = PyObject_CallMethodNoArgs(self, &_Py_ID(readline));
649 : :
650 [ # # ]: 0 : if (line == NULL)
651 : 0 : return NULL;
652 : :
653 [ # # ]: 0 : if (PyObject_Size(line) <= 0) {
654 : : /* Error or empty */
655 : 0 : Py_DECREF(line);
656 : 0 : return NULL;
657 : : }
658 : :
659 : 0 : return line;
660 : : }
661 : :
662 : : /*[clinic input]
663 : : _io._IOBase.readlines
664 : : hint: Py_ssize_t(accept={int, NoneType}) = -1
665 : : /
666 : :
667 : : Return a list of lines from the stream.
668 : :
669 : : hint can be specified to control the number of lines read: no more
670 : : lines will be read if the total size (in bytes/characters) of all
671 : : lines so far exceeds hint.
672 : : [clinic start generated code]*/
673 : :
674 : : static PyObject *
675 : 2 : _io__IOBase_readlines_impl(PyObject *self, Py_ssize_t hint)
676 : : /*[clinic end generated code: output=2f50421677fa3dea input=9400c786ea9dc416]*/
677 : : {
678 : 2 : Py_ssize_t length = 0;
679 : 2 : PyObject *result, *it = NULL;
680 : :
681 : 2 : result = PyList_New(0);
682 [ - + ]: 2 : if (result == NULL)
683 : 0 : return NULL;
684 : :
685 [ + - ]: 2 : if (hint <= 0) {
686 : : /* XXX special-casing this made sense in the Python version in order
687 : : to remove the bytecode interpretation overhead, but it could
688 : : probably be removed here. */
689 : 2 : PyObject *ret = PyObject_CallMethodObjArgs(result, &_Py_ID(extend),
690 : : self, NULL);
691 [ - + ]: 2 : if (ret == NULL) {
692 : 0 : goto error;
693 : : }
694 : 2 : Py_DECREF(ret);
695 : 2 : return result;
696 : : }
697 : :
698 : 0 : it = PyObject_GetIter(self);
699 [ # # ]: 0 : if (it == NULL) {
700 : 0 : goto error;
701 : : }
702 : :
703 : 0 : while (1) {
704 : : Py_ssize_t line_length;
705 : 0 : PyObject *line = PyIter_Next(it);
706 [ # # ]: 0 : if (line == NULL) {
707 [ # # ]: 0 : if (PyErr_Occurred()) {
708 : 0 : goto error;
709 : : }
710 : : else
711 : 0 : break; /* StopIteration raised */
712 : : }
713 : :
714 [ # # ]: 0 : if (PyList_Append(result, line) < 0) {
715 : 0 : Py_DECREF(line);
716 : 0 : goto error;
717 : : }
718 : 0 : line_length = PyObject_Size(line);
719 : 0 : Py_DECREF(line);
720 [ # # ]: 0 : if (line_length < 0) {
721 : 0 : goto error;
722 : : }
723 [ # # ]: 0 : if (line_length > hint - length)
724 : 0 : break;
725 : 0 : length += line_length;
726 : : }
727 : :
728 : 0 : Py_DECREF(it);
729 : 0 : return result;
730 : :
731 : 0 : error:
732 : 0 : Py_XDECREF(it);
733 : 0 : Py_DECREF(result);
734 : 0 : return NULL;
735 : : }
736 : :
737 : : /*[clinic input]
738 : : _io._IOBase.writelines
739 : : lines: object
740 : : /
741 : :
742 : : Write a list of lines to stream.
743 : :
744 : : Line separators are not added, so it is usual for each of the
745 : : lines provided to have a line separator at the end.
746 : : [clinic start generated code]*/
747 : :
748 : : static PyObject *
749 : 146492 : _io__IOBase_writelines(PyObject *self, PyObject *lines)
750 : : /*[clinic end generated code: output=976eb0a9b60a6628 input=cac3fc8864183359]*/
751 : : {
752 : : PyObject *iter, *res;
753 : :
754 [ - + ]: 146492 : if (iobase_check_closed(self))
755 : 0 : return NULL;
756 : :
757 : 146492 : iter = PyObject_GetIter(lines);
758 [ - + ]: 146492 : if (iter == NULL)
759 : 0 : return NULL;
760 : :
761 : 439476 : while (1) {
762 : 585968 : PyObject *line = PyIter_Next(iter);
763 [ + + ]: 585968 : if (line == NULL) {
764 [ - + ]: 146492 : if (PyErr_Occurred()) {
765 : 0 : Py_DECREF(iter);
766 : 0 : return NULL;
767 : : }
768 : : else
769 : 146492 : break; /* Stop Iteration */
770 : : }
771 : :
772 : 439476 : res = NULL;
773 : : do {
774 : 439476 : res = PyObject_CallMethodObjArgs(self, &_Py_ID(write), line, NULL);
775 [ - + - - ]: 439476 : } while (res == NULL && _PyIO_trap_eintr());
776 : 439476 : Py_DECREF(line);
777 [ - + ]: 439476 : if (res == NULL) {
778 : 0 : Py_DECREF(iter);
779 : 0 : return NULL;
780 : : }
781 : 439476 : Py_DECREF(res);
782 : : }
783 : 146492 : Py_DECREF(iter);
784 : 146492 : Py_RETURN_NONE;
785 : : }
786 : :
787 : : #include "clinic/iobase.c.h"
788 : :
789 : : static PyMethodDef iobase_methods[] = {
790 : : {"seek", iobase_seek, METH_VARARGS, iobase_seek_doc},
791 : : _IO__IOBASE_TELL_METHODDEF
792 : : {"truncate", iobase_truncate, METH_VARARGS, iobase_truncate_doc},
793 : : _IO__IOBASE_FLUSH_METHODDEF
794 : : _IO__IOBASE_CLOSE_METHODDEF
795 : :
796 : : _IO__IOBASE_SEEKABLE_METHODDEF
797 : : _IO__IOBASE_READABLE_METHODDEF
798 : : _IO__IOBASE_WRITABLE_METHODDEF
799 : :
800 : : {"_checkClosed", _PyIOBase_check_closed, METH_NOARGS},
801 : : {"_checkSeekable", _PyIOBase_check_seekable, METH_NOARGS},
802 : : {"_checkReadable", _PyIOBase_check_readable, METH_NOARGS},
803 : : {"_checkWritable", _PyIOBase_check_writable, METH_NOARGS},
804 : :
805 : : _IO__IOBASE_FILENO_METHODDEF
806 : : _IO__IOBASE_ISATTY_METHODDEF
807 : :
808 : : {"__enter__", iobase_enter, METH_NOARGS},
809 : : {"__exit__", iobase_exit, METH_VARARGS},
810 : :
811 : : _IO__IOBASE_READLINE_METHODDEF
812 : : _IO__IOBASE_READLINES_METHODDEF
813 : : _IO__IOBASE_WRITELINES_METHODDEF
814 : :
815 : : {NULL, NULL}
816 : : };
817 : :
818 : : static PyGetSetDef iobase_getset[] = {
819 : : {"__dict__", PyObject_GenericGetDict, NULL, NULL},
820 : : {"closed", (getter)iobase_closed_get, NULL, NULL},
821 : : {NULL}
822 : : };
823 : :
824 : :
825 : : PyTypeObject PyIOBase_Type = {
826 : : PyVarObject_HEAD_INIT(NULL, 0)
827 : : "_io._IOBase", /*tp_name*/
828 : : sizeof(iobase), /*tp_basicsize*/
829 : : 0, /*tp_itemsize*/
830 : : (destructor)iobase_dealloc, /*tp_dealloc*/
831 : : 0, /*tp_vectorcall_offset*/
832 : : 0, /*tp_getattr*/
833 : : 0, /*tp_setattr*/
834 : : 0, /*tp_as_async*/
835 : : 0, /*tp_repr*/
836 : : 0, /*tp_as_number*/
837 : : 0, /*tp_as_sequence*/
838 : : 0, /*tp_as_mapping*/
839 : : 0, /*tp_hash */
840 : : 0, /*tp_call*/
841 : : 0, /*tp_str*/
842 : : 0, /*tp_getattro*/
843 : : 0, /*tp_setattro*/
844 : : 0, /*tp_as_buffer*/
845 : : Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE
846 : : | Py_TPFLAGS_HAVE_GC, /*tp_flags*/
847 : : iobase_doc, /* tp_doc */
848 : : (traverseproc)iobase_traverse, /* tp_traverse */
849 : : (inquiry)iobase_clear, /* tp_clear */
850 : : 0, /* tp_richcompare */
851 : : offsetof(iobase, weakreflist), /* tp_weaklistoffset */
852 : : iobase_iter, /* tp_iter */
853 : : iobase_iternext, /* tp_iternext */
854 : : iobase_methods, /* tp_methods */
855 : : 0, /* tp_members */
856 : : iobase_getset, /* tp_getset */
857 : : 0, /* tp_base */
858 : : 0, /* tp_dict */
859 : : 0, /* tp_descr_get */
860 : : 0, /* tp_descr_set */
861 : : offsetof(iobase, dict), /* tp_dictoffset */
862 : : 0, /* tp_init */
863 : : 0, /* tp_alloc */
864 : : PyType_GenericNew, /* tp_new */
865 : : 0, /* tp_free */
866 : : 0, /* tp_is_gc */
867 : : 0, /* tp_bases */
868 : : 0, /* tp_mro */
869 : : 0, /* tp_cache */
870 : : 0, /* tp_subclasses */
871 : : 0, /* tp_weaklist */
872 : : 0, /* tp_del */
873 : : 0, /* tp_version_tag */
874 : : iobase_finalize, /* tp_finalize */
875 : : };
876 : :
877 : :
878 : : /*
879 : : * RawIOBase class, Inherits from IOBase.
880 : : */
881 : : PyDoc_STRVAR(rawiobase_doc,
882 : : "Base class for raw binary I/O.");
883 : :
884 : : /*
885 : : * The read() method is implemented by calling readinto(); derived classes
886 : : * that want to support read() only need to implement readinto() as a
887 : : * primitive operation. In general, readinto() can be more efficient than
888 : : * read().
889 : : *
890 : : * (It would be tempting to also provide an implementation of readinto() in
891 : : * terms of read(), in case the latter is a more suitable primitive operation,
892 : : * but that would lead to nasty recursion in case a subclass doesn't implement
893 : : * either.)
894 : : */
895 : :
896 : : /*[clinic input]
897 : : _io._RawIOBase.read
898 : : size as n: Py_ssize_t = -1
899 : : /
900 : : [clinic start generated code]*/
901 : :
902 : : static PyObject *
903 : 0 : _io__RawIOBase_read_impl(PyObject *self, Py_ssize_t n)
904 : : /*[clinic end generated code: output=6cdeb731e3c9f13c input=b6d0dcf6417d1374]*/
905 : : {
906 : : PyObject *b, *res;
907 : :
908 [ # # ]: 0 : if (n < 0) {
909 : 0 : return PyObject_CallMethodNoArgs(self, &_Py_ID(readall));
910 : : }
911 : :
912 : : /* TODO: allocate a bytes object directly instead and manually construct
913 : : a writable memoryview pointing to it. */
914 : 0 : b = PyByteArray_FromStringAndSize(NULL, n);
915 [ # # ]: 0 : if (b == NULL)
916 : 0 : return NULL;
917 : :
918 : 0 : res = PyObject_CallMethodObjArgs(self, &_Py_ID(readinto), b, NULL);
919 [ # # # # ]: 0 : if (res == NULL || res == Py_None) {
920 : 0 : Py_DECREF(b);
921 : 0 : return res;
922 : : }
923 : :
924 : 0 : n = PyNumber_AsSsize_t(res, PyExc_ValueError);
925 : 0 : Py_DECREF(res);
926 [ # # # # ]: 0 : if (n == -1 && PyErr_Occurred()) {
927 : 0 : Py_DECREF(b);
928 : 0 : return NULL;
929 : : }
930 : :
931 : 0 : res = PyBytes_FromStringAndSize(PyByteArray_AsString(b), n);
932 : 0 : Py_DECREF(b);
933 : 0 : return res;
934 : : }
935 : :
936 : :
937 : : /*[clinic input]
938 : : _io._RawIOBase.readall
939 : :
940 : : Read until EOF, using multiple read() call.
941 : : [clinic start generated code]*/
942 : :
943 : : static PyObject *
944 : 0 : _io__RawIOBase_readall_impl(PyObject *self)
945 : : /*[clinic end generated code: output=1987b9ce929425a0 input=688874141213622a]*/
946 : : {
947 : : int r;
948 : 0 : PyObject *chunks = PyList_New(0);
949 : : PyObject *result;
950 : :
951 [ # # ]: 0 : if (chunks == NULL)
952 : 0 : return NULL;
953 : :
954 : 0 : while (1) {
955 : 0 : PyObject *data = _PyObject_CallMethod(self, &_Py_ID(read),
956 : : "i", DEFAULT_BUFFER_SIZE);
957 [ # # ]: 0 : if (!data) {
958 : : /* NOTE: PyErr_SetFromErrno() calls PyErr_CheckSignals()
959 : : when EINTR occurs so we needn't do it ourselves. */
960 [ # # ]: 0 : if (_PyIO_trap_eintr()) {
961 : 0 : continue;
962 : : }
963 : 0 : Py_DECREF(chunks);
964 : 0 : return NULL;
965 : : }
966 [ # # ]: 0 : if (data == Py_None) {
967 [ # # ]: 0 : if (PyList_GET_SIZE(chunks) == 0) {
968 : 0 : Py_DECREF(chunks);
969 : 0 : return data;
970 : : }
971 : 0 : Py_DECREF(data);
972 : 0 : break;
973 : : }
974 [ # # ]: 0 : if (!PyBytes_Check(data)) {
975 : 0 : Py_DECREF(chunks);
976 : 0 : Py_DECREF(data);
977 : 0 : PyErr_SetString(PyExc_TypeError, "read() should return bytes");
978 : 0 : return NULL;
979 : : }
980 [ # # ]: 0 : if (PyBytes_GET_SIZE(data) == 0) {
981 : : /* EOF */
982 : 0 : Py_DECREF(data);
983 : 0 : break;
984 : : }
985 : 0 : r = PyList_Append(chunks, data);
986 : 0 : Py_DECREF(data);
987 [ # # ]: 0 : if (r < 0) {
988 : 0 : Py_DECREF(chunks);
989 : 0 : return NULL;
990 : : }
991 : : }
992 : 0 : result = _PyBytes_Join((PyObject *)&_Py_SINGLETON(bytes_empty), chunks);
993 : 0 : Py_DECREF(chunks);
994 : 0 : return result;
995 : : }
996 : :
997 : : static PyObject *
998 : 0 : rawiobase_readinto(PyObject *self, PyObject *args)
999 : : {
1000 : 0 : PyErr_SetNone(PyExc_NotImplementedError);
1001 : 0 : return NULL;
1002 : : }
1003 : :
1004 : : static PyObject *
1005 : 0 : rawiobase_write(PyObject *self, PyObject *args)
1006 : : {
1007 : 0 : PyErr_SetNone(PyExc_NotImplementedError);
1008 : 0 : return NULL;
1009 : : }
1010 : :
1011 : : static PyMethodDef rawiobase_methods[] = {
1012 : : _IO__RAWIOBASE_READ_METHODDEF
1013 : : _IO__RAWIOBASE_READALL_METHODDEF
1014 : : {"readinto", rawiobase_readinto, METH_VARARGS},
1015 : : {"write", rawiobase_write, METH_VARARGS},
1016 : : {NULL, NULL}
1017 : : };
1018 : :
1019 : : PyTypeObject PyRawIOBase_Type = {
1020 : : PyVarObject_HEAD_INIT(NULL, 0)
1021 : : "_io._RawIOBase", /*tp_name*/
1022 : : 0, /*tp_basicsize*/
1023 : : 0, /*tp_itemsize*/
1024 : : 0, /*tp_dealloc*/
1025 : : 0, /*tp_vectorcall_offset*/
1026 : : 0, /*tp_getattr*/
1027 : : 0, /*tp_setattr*/
1028 : : 0, /*tp_as_async*/
1029 : : 0, /*tp_repr*/
1030 : : 0, /*tp_as_number*/
1031 : : 0, /*tp_as_sequence*/
1032 : : 0, /*tp_as_mapping*/
1033 : : 0, /*tp_hash */
1034 : : 0, /*tp_call*/
1035 : : 0, /*tp_str*/
1036 : : 0, /*tp_getattro*/
1037 : : 0, /*tp_setattro*/
1038 : : 0, /*tp_as_buffer*/
1039 : : Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /*tp_flags*/
1040 : : rawiobase_doc, /* tp_doc */
1041 : : 0, /* tp_traverse */
1042 : : 0, /* tp_clear */
1043 : : 0, /* tp_richcompare */
1044 : : 0, /* tp_weaklistoffset */
1045 : : 0, /* tp_iter */
1046 : : 0, /* tp_iternext */
1047 : : rawiobase_methods, /* tp_methods */
1048 : : 0, /* tp_members */
1049 : : 0, /* tp_getset */
1050 : : &PyIOBase_Type, /* tp_base */
1051 : : 0, /* tp_dict */
1052 : : 0, /* tp_descr_get */
1053 : : 0, /* tp_descr_set */
1054 : : 0, /* tp_dictoffset */
1055 : : 0, /* tp_init */
1056 : : 0, /* tp_alloc */
1057 : : 0, /* tp_new */
1058 : : 0, /* tp_free */
1059 : : 0, /* tp_is_gc */
1060 : : 0, /* tp_bases */
1061 : : 0, /* tp_mro */
1062 : : 0, /* tp_cache */
1063 : : 0, /* tp_subclasses */
1064 : : 0, /* tp_weaklist */
1065 : : 0, /* tp_del */
1066 : : 0, /* tp_version_tag */
1067 : : 0, /* tp_finalize */
1068 : : };
|