blob: 9ee23264eef28b753982ca9a200526ca615d2756 [file] [log] [blame]
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +00001/*
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
20typedef struct {
21 PyObject_HEAD
22
23 PyObject *dict;
24 PyObject *weakreflist;
25} IOBaseObject;
26
27PyDoc_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 statment 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 */
65static PyObject *
66IOBase_unsupported(const char *message)
67{
68 PyErr_SetString(IO_STATE->unsupported_operation, message);
69 return NULL;
70}
71
72/* Positionning */
73
74PyDoc_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
87static PyObject *
88IOBase_seek(PyObject *self, PyObject *args)
89{
90 return IOBase_unsupported("seek");
91}
92
93PyDoc_STRVAR(IOBase_tell_doc,
94 "Return current stream position.");
95
96static PyObject *
97IOBase_tell(PyObject *self, PyObject *args)
98{
99 return PyObject_CallMethod(self, "seek", "ii", 0, 1);
100}
101
102PyDoc_STRVAR(IOBase_truncate_doc,
103 "Truncate file to size bytes.\n"
104 "\n"
105 "Size defaults to the current IO position as reported by tell(). Return\n"
106 "the new size.");
107
108static PyObject *
109IOBase_truncate(PyObject *self, PyObject *args)
110{
111 return IOBase_unsupported("truncate");
112}
113
114/* Flush and close methods */
115
116PyDoc_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
121static PyObject *
122IOBase_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
132PyDoc_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
137static int
138IOBase_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
152static PyObject *
153IOBase_closed_get(PyObject *self, void *context)
154{
155 return PyBool_FromLong(IS_CLOSED(self));
156}
157
158PyObject *
159_PyIOBase_checkClosed(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
175static PyObject *
176IOBase_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 /* If flush() fails, just give up */
187 if (PyErr_ExceptionMatches(PyExc_IOError))
188 PyErr_Clear();
189 else
190 return NULL;
191 }
192 Py_XDECREF(res);
193 Py_RETURN_NONE;
194}
195
196/* Finalization and garbage collection support */
197
198int
199_PyIOBase_finalize(PyObject *self)
200{
201 PyObject *res;
202 PyObject *tp, *v, *tb;
203 int closed = 1;
204 int is_zombie;
205
206 /* If _PyIOBase_finalize() is called from a destructor, we need to
207 resurrect the object as calling close() can invoke arbitrary code. */
208 is_zombie = (Py_REFCNT(self) == 0);
209 if (is_zombie) {
210 ++Py_REFCNT(self);
211 }
212 PyErr_Fetch(&tp, &v, &tb);
213 /* If `closed` doesn't exist or can't be evaluated as bool, then the
214 object is probably in an unusable state, so ignore. */
215 res = PyObject_GetAttr(self, _PyIO_str_closed);
216 if (res == NULL)
217 PyErr_Clear();
218 else {
219 closed = PyObject_IsTrue(res);
220 Py_DECREF(res);
221 if (closed == -1)
222 PyErr_Clear();
223 }
224 if (closed == 0) {
225 res = PyObject_CallMethodObjArgs((PyObject *) self, _PyIO_str_close,
226 NULL);
227 /* Silencing I/O errors is bad, but printing spurious tracebacks is
228 equally as bad, and potentially more frequent (because of
229 shutdown issues). */
230 if (res == NULL)
231 PyErr_Clear();
232 else
233 Py_DECREF(res);
234 }
235 PyErr_Restore(tp, v, tb);
236 if (is_zombie) {
237 if (--Py_REFCNT(self) != 0) {
238 /* The object lives again. The following code is taken from
239 slot_tp_del in typeobject.c. */
240 Py_ssize_t refcnt = Py_REFCNT(self);
241 _Py_NewReference(self);
242 Py_REFCNT(self) = refcnt;
243 /* If Py_REF_DEBUG, _Py_NewReference bumped _Py_RefTotal, so
244 * we need to undo that. */
245 _Py_DEC_REFTOTAL;
246 /* If Py_TRACE_REFS, _Py_NewReference re-added self to the object
247 * chain, so no more to do there.
248 * If COUNT_ALLOCS, the original decref bumped tp_frees, and
249 * _Py_NewReference bumped tp_allocs: both of those need to be
250 * undone.
251 */
252#ifdef COUNT_ALLOCS
253 --Py_TYPE(self)->tp_frees;
254 --Py_TYPE(self)->tp_allocs;
255#endif
256 return -1;
257 }
258 }
259 return 0;
260}
261
262static int
263IOBase_traverse(IOBaseObject *self, visitproc visit, void *arg)
264{
265 Py_VISIT(self->dict);
266 return 0;
267}
268
269static int
270IOBase_clear(IOBaseObject *self)
271{
272 if (_PyIOBase_finalize((PyObject *) self) < 0)
273 return -1;
274 Py_CLEAR(self->dict);
275 return 0;
276}
277
278/* Destructor */
279
280static void
281IOBase_dealloc(IOBaseObject *self)
282{
283 /* NOTE: since IOBaseObject has its own dict, Python-defined attributes
284 are still available here for close() to use.
285 However, if the derived class declares a __slots__, those slots are
286 already gone.
287 */
288 if (_PyIOBase_finalize((PyObject *) self) < 0) {
289 /* When called from a heap type's dealloc, the type will be
290 decref'ed on return (see e.g. subtype_dealloc in typeobject.c). */
291 if (PyType_HasFeature(Py_TYPE(self), Py_TPFLAGS_HEAPTYPE))
292 Py_INCREF(Py_TYPE(self));
293 return;
294 }
295 _PyObject_GC_UNTRACK(self);
296 if (self->weakreflist != NULL)
297 PyObject_ClearWeakRefs((PyObject *) self);
298 Py_CLEAR(self->dict);
299 Py_TYPE(self)->tp_free((PyObject *) self);
300}
301
302/* Inquiry methods */
303
304PyDoc_STRVAR(IOBase_seekable_doc,
305 "Return whether object supports random access.\n"
306 "\n"
307 "If False, seek(), tell() and truncate() will raise IOError.\n"
308 "This method may need to do a test seek().");
309
310static PyObject *
311IOBase_seekable(PyObject *self, PyObject *args)
312{
313 Py_RETURN_FALSE;
314}
315
316PyObject *
317_PyIOBase_checkSeekable(PyObject *self, PyObject *args)
318{
319 PyObject *res = PyObject_CallMethodObjArgs(self, _PyIO_str_seekable, NULL);
320 if (res == NULL)
321 return NULL;
322 if (res != Py_True) {
323 Py_CLEAR(res);
324 PyErr_SetString(PyExc_IOError, "File or stream is not seekable.");
325 return NULL;
326 }
327 if (args == Py_True) {
328 Py_DECREF(res);
329 }
330 return res;
331}
332
333PyDoc_STRVAR(IOBase_readable_doc,
334 "Return whether object was opened for reading.\n"
335 "\n"
336 "If False, read() will raise IOError.");
337
338static PyObject *
339IOBase_readable(PyObject *self, PyObject *args)
340{
341 Py_RETURN_FALSE;
342}
343
344/* May be called with any object */
345PyObject *
346_PyIOBase_checkReadable(PyObject *self, PyObject *args)
347{
348 PyObject *res = PyObject_CallMethodObjArgs(self, _PyIO_str_readable, NULL);
349 if (res == NULL)
350 return NULL;
351 if (res != Py_True) {
352 Py_CLEAR(res);
353 PyErr_SetString(PyExc_IOError, "File or stream is not readable.");
354 return NULL;
355 }
356 if (args == Py_True) {
357 Py_DECREF(res);
358 }
359 return res;
360}
361
362PyDoc_STRVAR(IOBase_writable_doc,
363 "Return whether object was opened for writing.\n"
364 "\n"
365 "If False, read() will raise IOError.");
366
367static PyObject *
368IOBase_writable(PyObject *self, PyObject *args)
369{
370 Py_RETURN_FALSE;
371}
372
373/* May be called with any object */
374PyObject *
375_PyIOBase_checkWritable(PyObject *self, PyObject *args)
376{
377 PyObject *res = PyObject_CallMethodObjArgs(self, _PyIO_str_writable, NULL);
378 if (res == NULL)
379 return NULL;
380 if (res != Py_True) {
381 Py_CLEAR(res);
382 PyErr_SetString(PyExc_IOError, "File or stream is not writable.");
383 return NULL;
384 }
385 if (args == Py_True) {
386 Py_DECREF(res);
387 }
388 return res;
389}
390
391/* Context manager */
392
393static PyObject *
394IOBase_enter(PyObject *self, PyObject *args)
395{
396 if (_PyIOBase_checkClosed(self, Py_True) == NULL)
397 return NULL;
398
399 Py_INCREF(self);
400 return self;
401}
402
403static PyObject *
404IOBase_exit(PyObject *self, PyObject *args)
405{
406 return PyObject_CallMethodObjArgs(self, _PyIO_str_close, NULL);
407}
408
409/* Lower-level APIs */
410
411/* XXX Should these be present even if unimplemented? */
412
413PyDoc_STRVAR(IOBase_fileno_doc,
414 "Returns underlying file descriptor if one exists.\n"
415 "\n"
416 "An IOError is raised if the IO object does not use a file descriptor.\n");
417
418static PyObject *
419IOBase_fileno(PyObject *self, PyObject *args)
420{
421 return IOBase_unsupported("fileno");
422}
423
424PyDoc_STRVAR(IOBase_isatty_doc,
425 "Return whether this is an 'interactive' stream.\n"
426 "\n"
427 "Return False if it can't be determined.\n");
428
429static PyObject *
430IOBase_isatty(PyObject *self, PyObject *args)
431{
432 if (_PyIOBase_checkClosed(self, Py_True) == NULL)
433 return NULL;
434 Py_RETURN_FALSE;
435}
436
437/* Readline(s) and writelines */
438
439PyDoc_STRVAR(IOBase_readline_doc,
440 "Read and return a line from the stream.\n"
441 "\n"
442 "If limit is specified, at most limit bytes will be read.\n"
443 "\n"
444 "The line terminator is always b'\n' for binary files; for text\n"
445 "files, the newlines argument to open can be used to select the line\n"
446 "terminator(s) recognized.\n");
447
448static PyObject *
449IOBase_readline(PyObject *self, PyObject *args)
450{
451 /* For backwards compatibility, a (slowish) readline(). */
452
453 Py_ssize_t limit = -1;
454 int has_peek = 0;
455 PyObject *buffer, *result;
456 Py_ssize_t old_size = -1;
457
458 if (!PyArg_ParseTuple(args, "|n:readline", &limit)) {
459 return NULL;
460 }
461
462 if (_PyIOBase_checkClosed(self, Py_True) == NULL)
463 return NULL;
464
465 if (PyObject_HasAttrString(self, "peek"))
466 has_peek = 1;
467
468 buffer = PyByteArray_FromStringAndSize(NULL, 0);
469 if (buffer == NULL)
470 return NULL;
471
472 while (limit < 0 || Py_SIZE(buffer) < limit) {
473 Py_ssize_t nreadahead = 1;
474 PyObject *b;
475
476 if (has_peek) {
477 PyObject *readahead = PyObject_CallMethod(self, "peek", "i", 1);
478 if (readahead == NULL)
479 goto fail;
480 if (!PyBytes_Check(readahead)) {
481 PyErr_Format(PyExc_IOError,
482 "peek() should have returned a bytes object, "
483 "not '%.200s'", Py_TYPE(readahead)->tp_name);
484 Py_DECREF(readahead);
485 goto fail;
486 }
487 if (PyBytes_GET_SIZE(readahead) > 0) {
488 Py_ssize_t n = 0;
489 const char *buf = PyBytes_AS_STRING(readahead);
490 if (limit >= 0) {
491 do {
492 if (n >= PyBytes_GET_SIZE(readahead) || n >= limit)
493 break;
494 if (buf[n++] == '\n')
495 break;
496 } while (1);
497 }
498 else {
499 do {
500 if (n >= PyBytes_GET_SIZE(readahead))
501 break;
502 if (buf[n++] == '\n')
503 break;
504 } while (1);
505 }
506 nreadahead = n;
507 }
508 Py_DECREF(readahead);
509 }
510
511 b = PyObject_CallMethod(self, "read", "n", nreadahead);
512 if (b == NULL)
513 goto fail;
514 if (!PyBytes_Check(b)) {
515 PyErr_Format(PyExc_IOError,
516 "read() should have returned a bytes object, "
517 "not '%.200s'", Py_TYPE(b)->tp_name);
518 Py_DECREF(b);
519 goto fail;
520 }
521 if (PyBytes_GET_SIZE(b) == 0) {
522 Py_DECREF(b);
523 break;
524 }
525
526 old_size = PyByteArray_GET_SIZE(buffer);
527 PyByteArray_Resize(buffer, old_size + PyBytes_GET_SIZE(b));
528 memcpy(PyByteArray_AS_STRING(buffer) + old_size,
529 PyBytes_AS_STRING(b), PyBytes_GET_SIZE(b));
530
531 Py_DECREF(b);
532
533 if (PyByteArray_AS_STRING(buffer)[PyByteArray_GET_SIZE(buffer) - 1] == '\n')
534 break;
535 }
536
537 result = PyBytes_FromStringAndSize(PyByteArray_AS_STRING(buffer),
538 PyByteArray_GET_SIZE(buffer));
539 Py_DECREF(buffer);
540 return result;
541 fail:
542 Py_DECREF(buffer);
543 return NULL;
544}
545
546static PyObject *
547IOBase_iter(PyObject *self)
548{
549 if (_PyIOBase_checkClosed(self, Py_True) == NULL)
550 return NULL;
551
552 Py_INCREF(self);
553 return self;
554}
555
556static PyObject *
557IOBase_iternext(PyObject *self)
558{
559 PyObject *line = PyObject_CallMethodObjArgs(self, _PyIO_str_readline, NULL);
560
561 if (line == NULL)
562 return NULL;
563
564 if (PyObject_Size(line) == 0) {
565 Py_DECREF(line);
566 return NULL;
567 }
568
569 return line;
570}
571
572PyDoc_STRVAR(IOBase_readlines_doc,
573 "Return a list of lines from the stream.\n"
574 "\n"
575 "hint can be specified to control the number of lines read: no more\n"
576 "lines will be read if the total size (in bytes/characters) of all\n"
577 "lines so far exceeds hint.");
578
579static PyObject *
580IOBase_readlines(PyObject *self, PyObject *args)
581{
582 Py_ssize_t hint = -1, length = 0;
583 PyObject *hintobj = Py_None, *result;
584
585 if (!PyArg_ParseTuple(args, "|O:readlines", &hintobj)) {
586 return NULL;
587 }
588 if (hintobj != Py_None) {
589 hint = PyNumber_AsSsize_t(hintobj, PyExc_ValueError);
590 if (hint == -1 && PyErr_Occurred())
591 return NULL;
592 }
593
594 result = PyList_New(0);
595 if (result == NULL)
596 return NULL;
597
598 if (hint <= 0) {
599 /* XXX special-casing this made sense in the Python version in order
600 to remove the bytecode interpretation overhead, but it could
601 probably be removed here. */
602 PyObject *ret = PyObject_CallMethod(result, "extend", "O", self);
603 if (ret == NULL) {
604 Py_DECREF(result);
605 return NULL;
606 }
607 Py_DECREF(ret);
608 return result;
609 }
610
611 while (1) {
612 PyObject *line = PyIter_Next(self);
613 if (line == NULL) {
614 if (PyErr_Occurred()) {
615 Py_DECREF(result);
616 return NULL;
617 }
618 else
619 break; /* StopIteration raised */
620 }
621
622 if (PyList_Append(result, line) < 0) {
623 Py_DECREF(line);
624 Py_DECREF(result);
625 return NULL;
626 }
627 length += PyObject_Size(line);
628 Py_DECREF(line);
629
630 if (length > hint)
631 break;
632 }
633 return result;
634}
635
636static PyObject *
637IOBase_writelines(PyObject *self, PyObject *args)
638{
639 PyObject *lines, *iter, *res;
640
641 if (!PyArg_ParseTuple(args, "O:writelines", &lines)) {
642 return NULL;
643 }
644
645 if (_PyIOBase_checkClosed(self, Py_True) == NULL)
646 return NULL;
647
648 iter = PyObject_GetIter(lines);
649 if (iter == NULL)
650 return NULL;
651
652 while (1) {
653 PyObject *line = PyIter_Next(iter);
654 if (line == NULL) {
655 if (PyErr_Occurred()) {
656 Py_DECREF(iter);
657 return NULL;
658 }
659 else
660 break; /* Stop Iteration */
661 }
662
663 res = PyObject_CallMethodObjArgs(self, _PyIO_str_write, line, NULL);
664 Py_DECREF(line);
665 if (res == NULL) {
666 Py_DECREF(iter);
667 return NULL;
668 }
669 Py_DECREF(res);
670 }
671 Py_DECREF(iter);
672 Py_RETURN_NONE;
673}
674
675static PyMethodDef IOBase_methods[] = {
676 {"seek", IOBase_seek, METH_VARARGS, IOBase_seek_doc},
677 {"tell", IOBase_tell, METH_NOARGS, IOBase_tell_doc},
678 {"truncate", IOBase_truncate, METH_VARARGS, IOBase_truncate_doc},
679 {"flush", IOBase_flush, METH_NOARGS, IOBase_flush_doc},
680 {"close", IOBase_close, METH_NOARGS, IOBase_close_doc},
681
682 {"seekable", IOBase_seekable, METH_NOARGS, IOBase_seekable_doc},
683 {"readable", IOBase_readable, METH_NOARGS, IOBase_readable_doc},
684 {"writable", IOBase_writable, METH_NOARGS, IOBase_writable_doc},
685
686 {"_checkClosed", _PyIOBase_checkClosed, METH_NOARGS},
687 {"_checkSeekable", _PyIOBase_checkSeekable, METH_NOARGS},
688 {"_checkReadable", _PyIOBase_checkReadable, METH_NOARGS},
689 {"_checkWritable", _PyIOBase_checkWritable, METH_NOARGS},
690
691 {"fileno", IOBase_fileno, METH_NOARGS, IOBase_fileno_doc},
692 {"isatty", IOBase_isatty, METH_NOARGS, IOBase_isatty_doc},
693
694 {"__enter__", IOBase_enter, METH_NOARGS},
695 {"__exit__", IOBase_exit, METH_VARARGS},
696
697 {"readline", IOBase_readline, METH_VARARGS, IOBase_readline_doc},
698 {"readlines", IOBase_readlines, METH_VARARGS, IOBase_readlines_doc},
699 {"writelines", IOBase_writelines, METH_VARARGS},
700
701 {NULL, NULL}
702};
703
704static PyGetSetDef IOBase_getset[] = {
705 {"closed", (getter)IOBase_closed_get, NULL, NULL},
706 {0}
707};
708
709
710PyTypeObject PyIOBase_Type = {
711 PyVarObject_HEAD_INIT(NULL, 0)
712 "_io._IOBase", /*tp_name*/
713 sizeof(IOBaseObject), /*tp_basicsize*/
714 0, /*tp_itemsize*/
715 (destructor)IOBase_dealloc, /*tp_dealloc*/
716 0, /*tp_print*/
717 0, /*tp_getattr*/
718 0, /*tp_setattr*/
719 0, /*tp_compare */
720 0, /*tp_repr*/
721 0, /*tp_as_number*/
722 0, /*tp_as_sequence*/
723 0, /*tp_as_mapping*/
724 0, /*tp_hash */
725 0, /*tp_call*/
726 0, /*tp_str*/
727 0, /*tp_getattro*/
728 0, /*tp_setattro*/
729 0, /*tp_as_buffer*/
730 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE
731 | Py_TPFLAGS_HAVE_GC, /*tp_flags*/
732 IOBase_doc, /* tp_doc */
733 (traverseproc)IOBase_traverse, /* tp_traverse */
734 (inquiry)IOBase_clear, /* tp_clear */
735 0, /* tp_richcompare */
736 offsetof(IOBaseObject, weakreflist), /* tp_weaklistoffset */
737 IOBase_iter, /* tp_iter */
738 IOBase_iternext, /* tp_iternext */
739 IOBase_methods, /* tp_methods */
740 0, /* tp_members */
741 IOBase_getset, /* tp_getset */
742 0, /* tp_base */
743 0, /* tp_dict */
744 0, /* tp_descr_get */
745 0, /* tp_descr_set */
746 offsetof(IOBaseObject, dict), /* tp_dictoffset */
747 0, /* tp_init */
748 0, /* tp_alloc */
749 PyType_GenericNew, /* tp_new */
750};
751
752
753/*
754 * RawIOBase class, Inherits from IOBase.
755 */
756PyDoc_STRVAR(RawIOBase_doc,
757 "Base class for raw binary I/O.");
758
759/*
760 * The read() method is implemented by calling readinto(); derived classes
761 * that want to support read() only need to implement readinto() as a
762 * primitive operation. In general, readinto() can be more efficient than
763 * read().
764 *
765 * (It would be tempting to also provide an implementation of readinto() in
766 * terms of read(), in case the latter is a more suitable primitive operation,
767 * but that would lead to nasty recursion in case a subclass doesn't implement
768 * either.)
769*/
770
771static PyObject *
772RawIOBase_read(PyObject *self, PyObject *args)
773{
774 Py_ssize_t n = -1;
775 PyObject *b, *res;
776
777 if (!PyArg_ParseTuple(args, "|n:read", &n)) {
778 return NULL;
779 }
780
781 if (n < 0)
782 return PyObject_CallMethod(self, "readall", NULL);
783
784 /* TODO: allocate a bytes object directly instead and manually construct
785 a writable memoryview pointing to it. */
786 b = PyByteArray_FromStringAndSize(NULL, n);
787 if (b == NULL)
788 return NULL;
789
790 res = PyObject_CallMethodObjArgs(self, _PyIO_str_readinto, b, NULL);
791 if (res == NULL) {
792 Py_DECREF(b);
793 return NULL;
794 }
795
796 n = PyNumber_AsSsize_t(res, PyExc_ValueError);
797 Py_DECREF(res);
798 if (n == -1 && PyErr_Occurred()) {
799 Py_DECREF(b);
800 return NULL;
801 }
802
803 res = PyBytes_FromStringAndSize(PyByteArray_AsString(b), n);
804 Py_DECREF(b);
805 return res;
806}
807
808
809PyDoc_STRVAR(RawIOBase_readall_doc,
810 "Read until EOF, using multiple read() call.");
811
812static PyObject *
813RawIOBase_readall(PyObject *self, PyObject *args)
814{
815 PyObject *b = NULL;
816 Py_ssize_t cursize = 0;
817
818 while (1) {
819 Py_ssize_t length;
820 PyObject *data = PyObject_CallMethod(self, "read",
821 "i", DEFAULT_BUFFER_SIZE);
822
823 if (!data) {
824 Py_XDECREF(b);
825 return NULL;
826 }
827
828 if (!PyBytes_Check(data)) {
829 Py_XDECREF(b);
830 Py_DECREF(data);
831 PyErr_SetString(PyExc_TypeError, "read() should return bytes");
832 return NULL;
833 }
834
835 length = Py_SIZE(data);
836
837 if (b == NULL)
838 b = data;
839 else if (length != 0) {
840
841 _PyBytes_Resize(&b, cursize + length);
842 if (b == NULL) {
843 Py_DECREF(data);
844 return NULL;
845 }
846
847 memcpy(PyBytes_AS_STRING(b) + cursize,
848 PyBytes_AS_STRING(data), length);
849 Py_DECREF(data);
850 }
851
852 if (length == 0)
853 break;
854 }
855
856 return b;
857
858}
859
860static PyMethodDef RawIOBase_methods[] = {
861 {"read", RawIOBase_read, METH_VARARGS},
862 {"readall", RawIOBase_readall, METH_NOARGS, RawIOBase_readall_doc},
863 {NULL, NULL}
864};
865
866PyTypeObject PyRawIOBase_Type = {
867 PyVarObject_HEAD_INIT(NULL, 0)
868 "_io._RawIOBase", /*tp_name*/
869 0, /*tp_basicsize*/
870 0, /*tp_itemsize*/
871 0, /*tp_dealloc*/
872 0, /*tp_print*/
873 0, /*tp_getattr*/
874 0, /*tp_setattr*/
875 0, /*tp_compare */
876 0, /*tp_repr*/
877 0, /*tp_as_number*/
878 0, /*tp_as_sequence*/
879 0, /*tp_as_mapping*/
880 0, /*tp_hash */
881 0, /*tp_call*/
882 0, /*tp_str*/
883 0, /*tp_getattro*/
884 0, /*tp_setattro*/
885 0, /*tp_as_buffer*/
886 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /*tp_flags*/
887 RawIOBase_doc, /* tp_doc */
888 0, /* tp_traverse */
889 0, /* tp_clear */
890 0, /* tp_richcompare */
891 0, /* tp_weaklistoffset */
892 0, /* tp_iter */
893 0, /* tp_iternext */
894 RawIOBase_methods, /* tp_methods */
895 0, /* tp_members */
896 0, /* tp_getset */
897 &PyIOBase_Type, /* tp_base */
898 0, /* tp_dict */
899 0, /* tp_descr_get */
900 0, /* tp_descr_set */
901 0, /* tp_dictoffset */
902 0, /* tp_init */
903 0, /* tp_alloc */
904 0, /* tp_new */
905};