No issues found
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 "structmember.h"
14 #include "_iomodule.h"
15
16 /*
17 * IOBase class, an abstract class
18 */
19
20 typedef struct {
21 PyObject_HEAD
22
23 PyObject *dict;
24 PyObject *weakreflist;
25 } iobase;
26
27 PyDoc_STRVAR(iobase_doc,
28 "The abstract base class for all I/O classes, acting on streams of\n"
29 "bytes. There is no public constructor.\n"
30 "\n"
31 "This class provides dummy implementations for many methods that\n"
32 "derived classes can override selectively; the default implementations\n"
33 "represent a file that cannot be read, written or seeked.\n"
34 "\n"
35 "Even though IOBase does not declare read, readinto, or write because\n"
36 "their signatures will vary, implementations and clients should\n"
37 "consider those methods part of the interface. Also, implementations\n"
38 "may raise a IOError when operations they do not support are called.\n"
39 "\n"
40 "The basic type used for binary data read from or written to a file is\n"
41 "bytes. bytearrays are accepted too, and in some cases (such as\n"
42 "readinto) needed. Text I/O classes work with str data.\n"
43 "\n"
44 "Note that calling any method (even inquiries) on a closed stream is\n"
45 "undefined. Implementations may raise IOError in this case.\n"
46 "\n"
47 "IOBase (and its subclasses) support the iterator protocol, meaning\n"
48 "that an IOBase object can be iterated over yielding the lines in a\n"
49 "stream.\n"
50 "\n"
51 "IOBase also supports the :keyword:`with` statement. In this example,\n"
52 "fp is closed after the suite of the with statement is complete:\n"
53 "\n"
54 "with open('spam.txt', 'r') as fp:\n"
55 " fp.write('Spam and eggs!')\n");
56
57 /* Use this macro whenever you want to check the internal `closed` status
58 of the IOBase object rather than the virtual `closed` attribute as returned
59 by whatever subclass. */
60
61 #define IS_CLOSED(self) \
62 PyObject_HasAttrString(self, "__IOBase_closed")
63
64 /* Internal methods */
65 static PyObject *
66 iobase_unsupported(const char *message)
67 {
68 PyErr_SetString(_PyIO_unsupported_operation, message);
69 return NULL;
70 }
71
72 /* Positionning */
73
74 PyDoc_STRVAR(iobase_seek_doc,
75 "Change stream position.\n"
76 "\n"
77 "Change the stream position to byte offset offset. offset is\n"
78 "interpreted relative to the position indicated by whence. Values\n"
79 "for whence are:\n"
80 "\n"
81 "* 0 -- start of stream (the default); offset should be zero or positive\n"
82 "* 1 -- current stream position; offset may be negative\n"
83 "* 2 -- end of stream; offset is usually negative\n"
84 "\n"
85 "Return the new absolute position.");
86
87 static PyObject *
88 iobase_seek(PyObject *self, PyObject *args)
89 {
90 return iobase_unsupported("seek");
91 }
92
93 PyDoc_STRVAR(iobase_tell_doc,
94 "Return current stream position.");
95
96 static PyObject *
97 iobase_tell(PyObject *self, PyObject *args)
98 {
99 return PyObject_CallMethod(self, "seek", "ii", 0, 1);
100 }
101
102 PyDoc_STRVAR(iobase_truncate_doc,
103 "Truncate file to size bytes.\n"
104 "\n"
105 "File pointer is left unchanged. Size defaults to the current IO\n"
106 "position as reported by tell(). Returns the new size.");
107
108 static PyObject *
109 iobase_truncate(PyObject *self, PyObject *args)
110 {
111 return iobase_unsupported("truncate");
112 }
113
114 /* Flush and close methods */
115
116 PyDoc_STRVAR(iobase_flush_doc,
117 "Flush write buffers, if applicable.\n"
118 "\n"
119 "This is not implemented for read-only and non-blocking streams.\n");
120
121 static PyObject *
122 iobase_flush(PyObject *self, PyObject *args)
123 {
124 /* XXX Should this return the number of bytes written??? */
125 if (IS_CLOSED(self)) {
126 PyErr_SetString(PyExc_ValueError, "I/O operation on closed file.");
127 return NULL;
128 }
129 Py_RETURN_NONE;
130 }
131
132 PyDoc_STRVAR(iobase_close_doc,
133 "Flush and close the IO object.\n"
134 "\n"
135 "This method has no effect if the file is already closed.\n");
136
137 static int
138 iobase_closed(PyObject *self)
139 {
140 PyObject *res;
141 int closed;
142 /* This gets the derived attribute, which is *not* __IOBase_closed
143 in most cases! */
144 res = PyObject_GetAttr(self, _PyIO_str_closed);
145 if (res == NULL)
146 return 0;
147 closed = PyObject_IsTrue(res);
148 Py_DECREF(res);
149 return closed;
150 }
151
152 static PyObject *
153 iobase_closed_get(PyObject *self, void *context)
154 {
155 return PyBool_FromLong(IS_CLOSED(self));
156 }
157
158 PyObject *
159 _PyIOBase_check_closed(PyObject *self, PyObject *args)
160 {
161 if (iobase_closed(self)) {
162 PyErr_SetString(PyExc_ValueError, "I/O operation on closed file.");
163 return NULL;
164 }
165 if (args == Py_True)
166 return Py_None;
167 else
168 Py_RETURN_NONE;
169 }
170
171 /* XXX: IOBase thinks it has to maintain its own internal state in
172 `__IOBase_closed` and call flush() by itself, but it is redundant with
173 whatever behaviour a non-trivial derived class will implement. */
174
175 static PyObject *
176 iobase_close(PyObject *self, PyObject *args)
177 {
178 PyObject *res;
179
180 if (IS_CLOSED(self))
181 Py_RETURN_NONE;
182
183 res = PyObject_CallMethodObjArgs(self, _PyIO_str_flush, NULL);
184 PyObject_SetAttrString(self, "__IOBase_closed", Py_True);
185 if (res == NULL) {
186 return NULL;
187 }
188 Py_XDECREF(res);
189 Py_RETURN_NONE;
190 }
191
192 /* Finalization and garbage collection support */
193
194 int
195 _PyIOBase_finalize(PyObject *self)
196 {
197 PyObject *res;
198 PyObject *tp, *v, *tb;
199 int closed = 1;
200 int is_zombie;
201
202 /* If _PyIOBase_finalize() is called from a destructor, we need to
203 resurrect the object as calling close() can invoke arbitrary code. */
204 is_zombie = (Py_REFCNT(self) == 0);
205 if (is_zombie) {
206 ++Py_REFCNT(self);
207 }
208 PyErr_Fetch(&tp, &v, &tb);
209 /* If `closed` doesn't exist or can't be evaluated as bool, then the
210 object is probably in an unusable state, so ignore. */
211 res = PyObject_GetAttr(self, _PyIO_str_closed);
212 if (res == NULL)
213 PyErr_Clear();
214 else {
215 closed = PyObject_IsTrue(res);
216 Py_DECREF(res);
217 if (closed == -1)
218 PyErr_Clear();
219 }
220 if (closed == 0) {
221 res = PyObject_CallMethodObjArgs((PyObject *) self, _PyIO_str_close,
222 NULL);
223 /* Silencing I/O errors is bad, but printing spurious tracebacks is
224 equally as bad, and potentially more frequent (because of
225 shutdown issues). */
226 if (res == NULL)
227 PyErr_Clear();
228 else
229 Py_DECREF(res);
230 }
231 PyErr_Restore(tp, v, tb);
232 if (is_zombie) {
233 if (--Py_REFCNT(self) != 0) {
234 /* The object lives again. The following code is taken from
235 slot_tp_del in typeobject.c. */
236 Py_ssize_t refcnt = Py_REFCNT(self);
237 _Py_NewReference(self);
238 Py_REFCNT(self) = refcnt;
239 /* If Py_REF_DEBUG, _Py_NewReference bumped _Py_RefTotal, so
240 * we need to undo that. */
241 _Py_DEC_REFTOTAL;
242 /* If Py_TRACE_REFS, _Py_NewReference re-added self to the object
243 * chain, so no more to do there.
244 * If COUNT_ALLOCS, the original decref bumped tp_frees, and
245 * _Py_NewReference bumped tp_allocs: both of those need to be
246 * undone.
247 */
248 #ifdef COUNT_ALLOCS
249 --Py_TYPE(self)->tp_frees;
250 --Py_TYPE(self)->tp_allocs;
251 #endif
252 return -1;
253 }
254 }
255 return 0;
256 }
257
258 static int
259 iobase_traverse(iobase *self, visitproc visit, void *arg)
260 {
261 Py_VISIT(self->dict);
262 return 0;
263 }
264
265 static int
266 iobase_clear(iobase *self)
267 {
268 if (_PyIOBase_finalize((PyObject *) self) < 0)
269 return -1;
270 Py_CLEAR(self->dict);
271 return 0;
272 }
273
274 /* Destructor */
275
276 static void
277 iobase_dealloc(iobase *self)
278 {
279 /* NOTE: since IOBaseObject has its own dict, Python-defined attributes
280 are still available here for close() to use.
281 However, if the derived class declares a __slots__, those slots are
282 already gone.
283 */
284 if (_PyIOBase_finalize((PyObject *) self) < 0) {
285 /* When called from a heap type's dealloc, the type will be
286 decref'ed on return (see e.g. subtype_dealloc in typeobject.c). */
287 if (PyType_HasFeature(Py_TYPE(self), Py_TPFLAGS_HEAPTYPE))
288 Py_INCREF(Py_TYPE(self));
289 return;
290 }
291 _PyObject_GC_UNTRACK(self);
292 if (self->weakreflist != NULL)
293 PyObject_ClearWeakRefs((PyObject *) self);
294 Py_CLEAR(self->dict);
295 Py_TYPE(self)->tp_free((PyObject *) self);
296 }
297
298 /* Inquiry methods */
299
300 PyDoc_STRVAR(iobase_seekable_doc,
301 "Return whether object supports random access.\n"
302 "\n"
303 "If False, seek(), tell() and truncate() will raise IOError.\n"
304 "This method may need to do a test seek().");
305
306 static PyObject *
307 iobase_seekable(PyObject *self, PyObject *args)
308 {
309 Py_RETURN_FALSE;
310 }
311
312 PyObject *
313 _PyIOBase_check_seekable(PyObject *self, PyObject *args)
314 {
315 PyObject *res = PyObject_CallMethodObjArgs(self, _PyIO_str_seekable, NULL);
316 if (res == NULL)
317 return NULL;
318 if (res != Py_True) {
319 Py_CLEAR(res);
320 PyErr_SetString(PyExc_IOError, "File or stream is not seekable.");
321 return NULL;
322 }
323 if (args == Py_True) {
324 Py_DECREF(res);
325 }
326 return res;
327 }
328
329 PyDoc_STRVAR(iobase_readable_doc,
330 "Return whether object was opened for reading.\n"
331 "\n"
332 "If False, read() will raise IOError.");
333
334 static PyObject *
335 iobase_readable(PyObject *self, PyObject *args)
336 {
337 Py_RETURN_FALSE;
338 }
339
340 /* May be called with any object */
341 PyObject *
342 _PyIOBase_check_readable(PyObject *self, PyObject *args)
343 {
344 PyObject *res = PyObject_CallMethodObjArgs(self, _PyIO_str_readable, NULL);
345 if (res == NULL)
346 return NULL;
347 if (res != Py_True) {
348 Py_CLEAR(res);
349 PyErr_SetString(PyExc_IOError, "File or stream is not readable.");
350 return NULL;
351 }
352 if (args == Py_True) {
353 Py_DECREF(res);
354 }
355 return res;
356 }
357
358 PyDoc_STRVAR(iobase_writable_doc,
359 "Return whether object was opened for writing.\n"
360 "\n"
361 "If False, read() will raise IOError.");
362
363 static PyObject *
364 iobase_writable(PyObject *self, PyObject *args)
365 {
366 Py_RETURN_FALSE;
367 }
368
369 /* May be called with any object */
370 PyObject *
371 _PyIOBase_check_writable(PyObject *self, PyObject *args)
372 {
373 PyObject *res = PyObject_CallMethodObjArgs(self, _PyIO_str_writable, NULL);
374 if (res == NULL)
375 return NULL;
376 if (res != Py_True) {
377 Py_CLEAR(res);
378 PyErr_SetString(PyExc_IOError, "File or stream is not writable.");
379 return NULL;
380 }
381 if (args == Py_True) {
382 Py_DECREF(res);
383 }
384 return res;
385 }
386
387 /* Context manager */
388
389 static PyObject *
390 iobase_enter(PyObject *self, PyObject *args)
391 {
392 if (_PyIOBase_check_closed(self, Py_True) == NULL)
393 return NULL;
394
395 Py_INCREF(self);
396 return self;
397 }
398
399 static PyObject *
400 iobase_exit(PyObject *self, PyObject *args)
401 {
402 return PyObject_CallMethodObjArgs(self, _PyIO_str_close, NULL);
403 }
404
405 /* Lower-level APIs */
406
407 /* XXX Should these be present even if unimplemented? */
408
409 PyDoc_STRVAR(iobase_fileno_doc,
410 "Returns underlying file descriptor if one exists.\n"
411 "\n"
412 "An IOError is raised if the IO object does not use a file descriptor.\n");
413
414 static PyObject *
415 iobase_fileno(PyObject *self, PyObject *args)
416 {
417 return iobase_unsupported("fileno");
418 }
419
420 PyDoc_STRVAR(iobase_isatty_doc,
421 "Return whether this is an 'interactive' stream.\n"
422 "\n"
423 "Return False if it can't be determined.\n");
424
425 static PyObject *
426 iobase_isatty(PyObject *self, PyObject *args)
427 {
428 if (_PyIOBase_check_closed(self, Py_True) == NULL)
429 return NULL;
430 Py_RETURN_FALSE;
431 }
432
433 /* Readline(s) and writelines */
434
435 PyDoc_STRVAR(iobase_readline_doc,
436 "Read and return a line from the stream.\n"
437 "\n"
438 "If limit is specified, at most limit bytes will be read.\n"
439 "\n"
440 "The line terminator is always b'\n' for binary files; for text\n"
441 "files, the newlines argument to open can be used to select the line\n"
442 "terminator(s) recognized.\n");
443
444 static PyObject *
445 iobase_readline(PyObject *self, PyObject *args)
446 {
447 /* For backwards compatibility, a (slowish) readline(). */
448
449 Py_ssize_t limit = -1;
450 int has_peek = 0;
451 PyObject *buffer, *result;
452 Py_ssize_t old_size = -1;
453
454 if (!PyArg_ParseTuple(args, "|O&:readline", &_PyIO_ConvertSsize_t, &limit)) {
455 return NULL;
456 }
457
458 if (PyObject_HasAttrString(self, "peek"))
459 has_peek = 1;
460
461 buffer = PyByteArray_FromStringAndSize(NULL, 0);
462 if (buffer == NULL)
463 return NULL;
464
465 while (limit < 0 || Py_SIZE(buffer) < limit) {
466 Py_ssize_t nreadahead = 1;
467 PyObject *b;
468
469 if (has_peek) {
470 PyObject *readahead = PyObject_CallMethod(self, "peek", "i", 1);
471 if (readahead == NULL)
472 goto fail;
473 if (!PyBytes_Check(readahead)) {
474 PyErr_Format(PyExc_IOError,
475 "peek() should have returned a bytes object, "
476 "not '%.200s'", Py_TYPE(readahead)->tp_name);
477 Py_DECREF(readahead);
478 goto fail;
479 }
480 if (PyBytes_GET_SIZE(readahead) > 0) {
481 Py_ssize_t n = 0;
482 const char *buf = PyBytes_AS_STRING(readahead);
483 if (limit >= 0) {
484 do {
485 if (n >= PyBytes_GET_SIZE(readahead) || n >= limit)
486 break;
487 if (buf[n++] == '\n')
488 break;
489 } while (1);
490 }
491 else {
492 do {
493 if (n >= PyBytes_GET_SIZE(readahead))
494 break;
495 if (buf[n++] == '\n')
496 break;
497 } while (1);
498 }
499 nreadahead = n;
500 }
501 Py_DECREF(readahead);
502 }
503
504 b = PyObject_CallMethod(self, "read", "n", nreadahead);
505 if (b == NULL)
506 goto fail;
507 if (!PyBytes_Check(b)) {
508 PyErr_Format(PyExc_IOError,
509 "read() should have returned a bytes object, "
510 "not '%.200s'", Py_TYPE(b)->tp_name);
511 Py_DECREF(b);
512 goto fail;
513 }
514 if (PyBytes_GET_SIZE(b) == 0) {
515 Py_DECREF(b);
516 break;
517 }
518
519 old_size = PyByteArray_GET_SIZE(buffer);
520 PyByteArray_Resize(buffer, old_size + PyBytes_GET_SIZE(b));
521 memcpy(PyByteArray_AS_STRING(buffer) + old_size,
522 PyBytes_AS_STRING(b), PyBytes_GET_SIZE(b));
523
524 Py_DECREF(b);
525
526 if (PyByteArray_AS_STRING(buffer)[PyByteArray_GET_SIZE(buffer) - 1] == '\n')
527 break;
528 }
529
530 result = PyBytes_FromStringAndSize(PyByteArray_AS_STRING(buffer),
531 PyByteArray_GET_SIZE(buffer));
532 Py_DECREF(buffer);
533 return result;
534 fail:
535 Py_DECREF(buffer);
536 return NULL;
537 }
538
539 static PyObject *
540 iobase_iter(PyObject *self)
541 {
542 if (_PyIOBase_check_closed(self, Py_True) == NULL)
543 return NULL;
544
545 Py_INCREF(self);
546 return self;
547 }
548
549 static PyObject *
550 iobase_iternext(PyObject *self)
551 {
552 PyObject *line = PyObject_CallMethodObjArgs(self, _PyIO_str_readline, NULL);
553
554 if (line == NULL)
555 return NULL;
556
557 if (PyObject_Size(line) == 0) {
558 Py_DECREF(line);
559 return NULL;
560 }
561
562 return line;
563 }
564
565 PyDoc_STRVAR(iobase_readlines_doc,
566 "Return a list of lines from the stream.\n"
567 "\n"
568 "hint can be specified to control the number of lines read: no more\n"
569 "lines will be read if the total size (in bytes/characters) of all\n"
570 "lines so far exceeds hint.");
571
572 static PyObject *
573 iobase_readlines(PyObject *self, PyObject *args)
574 {
575 Py_ssize_t hint = -1, length = 0;
576 PyObject *result;
577
578 if (!PyArg_ParseTuple(args, "|O&:readlines", &_PyIO_ConvertSsize_t, &hint)) {
579 return NULL;
580 }
581
582 result = PyList_New(0);
583 if (result == NULL)
584 return NULL;
585
586 if (hint <= 0) {
587 /* XXX special-casing this made sense in the Python version in order
588 to remove the bytecode interpretation overhead, but it could
589 probably be removed here. */
590 PyObject *ret = PyObject_CallMethod(result, "extend", "O", self);
591 if (ret == NULL) {
592 Py_DECREF(result);
593 return NULL;
594 }
595 Py_DECREF(ret);
596 return result;
597 }
598
599 while (1) {
600 PyObject *line = PyIter_Next(self);
601 if (line == NULL) {
602 if (PyErr_Occurred()) {
603 Py_DECREF(result);
604 return NULL;
605 }
606 else
607 break; /* StopIteration raised */
608 }
609
610 if (PyList_Append(result, line) < 0) {
611 Py_DECREF(line);
612 Py_DECREF(result);
613 return NULL;
614 }
615 length += PyObject_Size(line);
616 Py_DECREF(line);
617
618 if (length > hint)
619 break;
620 }
621 return result;
622 }
623
624 static PyObject *
625 iobase_writelines(PyObject *self, PyObject *args)
626 {
627 PyObject *lines, *iter, *res;
628
629 if (!PyArg_ParseTuple(args, "O:writelines", &lines)) {
630 return NULL;
631 }
632
633 if (_PyIOBase_check_closed(self, Py_True) == NULL)
634 return NULL;
635
636 iter = PyObject_GetIter(lines);
637 if (iter == NULL)
638 return NULL;
639
640 while (1) {
641 PyObject *line = PyIter_Next(iter);
642 if (line == NULL) {
643 if (PyErr_Occurred()) {
644 Py_DECREF(iter);
645 return NULL;
646 }
647 else
648 break; /* Stop Iteration */
649 }
650
651 res = PyObject_CallMethodObjArgs(self, _PyIO_str_write, line, NULL);
652 Py_DECREF(line);
653 if (res == NULL) {
654 Py_DECREF(iter);
655 return NULL;
656 }
657 Py_DECREF(res);
658 }
659 Py_DECREF(iter);
660 Py_RETURN_NONE;
661 }
662
663 static PyMethodDef iobase_methods[] = {
664 {"seek", iobase_seek, METH_VARARGS, iobase_seek_doc},
665 {"tell", iobase_tell, METH_NOARGS, iobase_tell_doc},
666 {"truncate", iobase_truncate, METH_VARARGS, iobase_truncate_doc},
667 {"flush", iobase_flush, METH_NOARGS, iobase_flush_doc},
668 {"close", iobase_close, METH_NOARGS, iobase_close_doc},
669
670 {"seekable", iobase_seekable, METH_NOARGS, iobase_seekable_doc},
671 {"readable", iobase_readable, METH_NOARGS, iobase_readable_doc},
672 {"writable", iobase_writable, METH_NOARGS, iobase_writable_doc},
673
674 {"_checkClosed", _PyIOBase_check_closed, METH_NOARGS},
675 {"_checkSeekable", _PyIOBase_check_seekable, METH_NOARGS},
676 {"_checkReadable", _PyIOBase_check_readable, METH_NOARGS},
677 {"_checkWritable", _PyIOBase_check_writable, METH_NOARGS},
678
679 {"fileno", iobase_fileno, METH_NOARGS, iobase_fileno_doc},
680 {"isatty", iobase_isatty, METH_NOARGS, iobase_isatty_doc},
681
682 {"__enter__", iobase_enter, METH_NOARGS},
683 {"__exit__", iobase_exit, METH_VARARGS},
684
685 {"readline", iobase_readline, METH_VARARGS, iobase_readline_doc},
686 {"readlines", iobase_readlines, METH_VARARGS, iobase_readlines_doc},
687 {"writelines", iobase_writelines, METH_VARARGS},
688
689 {NULL, NULL}
690 };
691
692 static PyGetSetDef iobase_getset[] = {
693 {"closed", (getter)iobase_closed_get, NULL, NULL},
694 {NULL}
695 };
696
697
698 PyTypeObject PyIOBase_Type = {
699 PyVarObject_HEAD_INIT(NULL, 0)
700 "_io._IOBase", /*tp_name*/
701 sizeof(iobase), /*tp_basicsize*/
702 0, /*tp_itemsize*/
703 (destructor)iobase_dealloc, /*tp_dealloc*/
704 0, /*tp_print*/
705 0, /*tp_getattr*/
706 0, /*tp_setattr*/
707 0, /*tp_compare */
708 0, /*tp_repr*/
709 0, /*tp_as_number*/
710 0, /*tp_as_sequence*/
711 0, /*tp_as_mapping*/
712 0, /*tp_hash */
713 0, /*tp_call*/
714 0, /*tp_str*/
715 0, /*tp_getattro*/
716 0, /*tp_setattro*/
717 0, /*tp_as_buffer*/
718 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE
719 | Py_TPFLAGS_HAVE_GC, /*tp_flags*/
720 iobase_doc, /* tp_doc */
721 (traverseproc)iobase_traverse, /* tp_traverse */
722 (inquiry)iobase_clear, /* tp_clear */
723 0, /* tp_richcompare */
724 offsetof(iobase, weakreflist), /* tp_weaklistoffset */
725 iobase_iter, /* tp_iter */
726 iobase_iternext, /* tp_iternext */
727 iobase_methods, /* tp_methods */
728 0, /* tp_members */
729 iobase_getset, /* tp_getset */
730 0, /* tp_base */
731 0, /* tp_dict */
732 0, /* tp_descr_get */
733 0, /* tp_descr_set */
734 offsetof(iobase, dict), /* tp_dictoffset */
735 0, /* tp_init */
736 0, /* tp_alloc */
737 PyType_GenericNew, /* tp_new */
738 };
739
740
741 /*
742 * RawIOBase class, Inherits from IOBase.
743 */
744 PyDoc_STRVAR(rawiobase_doc,
745 "Base class for raw binary I/O.");
746
747 /*
748 * The read() method is implemented by calling readinto(); derived classes
749 * that want to support read() only need to implement readinto() as a
750 * primitive operation. In general, readinto() can be more efficient than
751 * read().
752 *
753 * (It would be tempting to also provide an implementation of readinto() in
754 * terms of read(), in case the latter is a more suitable primitive operation,
755 * but that would lead to nasty recursion in case a subclass doesn't implement
756 * either.)
757 */
758
759 static PyObject *
760 rawiobase_read(PyObject *self, PyObject *args)
761 {
762 Py_ssize_t n = -1;
763 PyObject *b, *res;
764
765 if (!PyArg_ParseTuple(args, "|n:read", &n)) {
766 return NULL;
767 }
768
769 if (n < 0)
770 return PyObject_CallMethod(self, "readall", NULL);
771
772 /* TODO: allocate a bytes object directly instead and manually construct
773 a writable memoryview pointing to it. */
774 b = PyByteArray_FromStringAndSize(NULL, n);
775 if (b == NULL)
776 return NULL;
777
778 res = PyObject_CallMethodObjArgs(self, _PyIO_str_readinto, b, NULL);
779 if (res == NULL || res == Py_None) {
780 Py_DECREF(b);
781 return res;
782 }
783
784 n = PyNumber_AsSsize_t(res, PyExc_ValueError);
785 Py_DECREF(res);
786 if (n == -1 && PyErr_Occurred()) {
787 Py_DECREF(b);
788 return NULL;
789 }
790
791 res = PyBytes_FromStringAndSize(PyByteArray_AsString(b), n);
792 Py_DECREF(b);
793 return res;
794 }
795
796
797 PyDoc_STRVAR(rawiobase_readall_doc,
798 "Read until EOF, using multiple read() call.");
799
800 static PyObject *
801 rawiobase_readall(PyObject *self, PyObject *args)
802 {
803 int r;
804 PyObject *chunks = PyList_New(0);
805 PyObject *result;
806
807 if (chunks == NULL)
808 return NULL;
809
810 while (1) {
811 PyObject *data = PyObject_CallMethod(self, "read",
812 "i", DEFAULT_BUFFER_SIZE);
813 if (!data) {
814 Py_DECREF(chunks);
815 return NULL;
816 }
817 if (data == Py_None) {
818 if (PyList_GET_SIZE(chunks) == 0) {
819 Py_DECREF(chunks);
820 return data;
821 }
822 Py_DECREF(data);
823 break;
824 }
825 if (!PyBytes_Check(data)) {
826 Py_DECREF(chunks);
827 Py_DECREF(data);
828 PyErr_SetString(PyExc_TypeError, "read() should return bytes");
829 return NULL;
830 }
831 if (PyBytes_GET_SIZE(data) == 0) {
832 /* EOF */
833 Py_DECREF(data);
834 break;
835 }
836 r = PyList_Append(chunks, data);
837 Py_DECREF(data);
838 if (r < 0) {
839 Py_DECREF(chunks);
840 return NULL;
841 }
842 }
843 result = _PyBytes_Join(_PyIO_empty_bytes, chunks);
844 Py_DECREF(chunks);
845 return result;
846 }
847
848 static PyMethodDef rawiobase_methods[] = {
849 {"read", rawiobase_read, METH_VARARGS},
850 {"readall", rawiobase_readall, METH_NOARGS, rawiobase_readall_doc},
851 {NULL, NULL}
852 };
853
854 PyTypeObject PyRawIOBase_Type = {
855 PyVarObject_HEAD_INIT(NULL, 0)
856 "_io._RawIOBase", /*tp_name*/
857 0, /*tp_basicsize*/
858 0, /*tp_itemsize*/
859 0, /*tp_dealloc*/
860 0, /*tp_print*/
861 0, /*tp_getattr*/
862 0, /*tp_setattr*/
863 0, /*tp_compare */
864 0, /*tp_repr*/
865 0, /*tp_as_number*/
866 0, /*tp_as_sequence*/
867 0, /*tp_as_mapping*/
868 0, /*tp_hash */
869 0, /*tp_call*/
870 0, /*tp_str*/
871 0, /*tp_getattro*/
872 0, /*tp_setattro*/
873 0, /*tp_as_buffer*/
874 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /*tp_flags*/
875 rawiobase_doc, /* tp_doc */
876 0, /* tp_traverse */
877 0, /* tp_clear */
878 0, /* tp_richcompare */
879 0, /* tp_weaklistoffset */
880 0, /* tp_iter */
881 0, /* tp_iternext */
882 rawiobase_methods, /* tp_methods */
883 0, /* tp_members */
884 0, /* tp_getset */
885 &PyIOBase_Type, /* tp_base */
886 0, /* tp_dict */
887 0, /* tp_descr_get */
888 0, /* tp_descr_set */
889 0, /* tp_dictoffset */
890 0, /* tp_init */
891 0, /* tp_alloc */
892 0, /* tp_new */
893 };