Rietveld Code Review Tool
Help | Bug tracker | Discussion group | Source code | Sign in
(1273)

Unified Diff: Modules/_iobase.c

Issue 22061: [issue4565] Rewrite the IO stack in C (Closed) Base URL: http://svn.python.org/view/*checkout*/python/branches/py3k/
Patch Set: Created 15 years ago
Use n/p to move between diff chunks; N/P to move between comments. Please Sign in to add in-line comments.
Jump to:
View side-by-side diff with in-line comments
Download patch
« Lib/_pyio.py ('K') | « Modules/_fileio.c ('k') | Modules/_iomodule.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: Modules/_iobase.c
===================================================================
--- Modules/_iobase.c (.../py3k) (révision 0)
+++ Modules/_iobase.c (.../io-c) (révision 70115)
@@ -0,0 +1,902 @@
+/*
+ An implementation of the I/O abstract base classes hierarchy
+ as defined by PEP 3116 - "New I/O"
+
+ Classes defined here: IOBase, RawIOBase.
+
+ Written by Amaury Forgeot d'Arc and Antoine Pitrou
+*/
+
+
+#define PY_SSIZE_T_CLEAN
+#include "Python.h"
+#include "structmember.h"
+#include "_iomodule.h"
+
+/*
+ * IOBase class, an abstract class
+ */
+
+typedef struct {
+ PyObject_HEAD
+
+ PyObject *dict;
+ PyObject *weakreflist;
+} IOBaseObject;
+
+PyDoc_STRVAR(IOBase_doc,
+ "The abstract base class for all I/O classes, acting on streams of\n"
+ "bytes. There is no public constructor.\n"
+ "\n"
+ "This class provides dummy implementations for many methods that\n"
+ "derived classes can override selectively; the default implementations\n"
+ "represent a file that cannot be read, written or seeked.\n"
+ "\n"
+ "Even though IOBase does not declare read, readinto, or write because\n"
+ "their signatures will vary, implementations and clients should\n"
+ "consider those methods part of the interface. Also, implementations\n"
+ "may raise a IOError when operations they do not support are called.\n"
+ "\n"
+ "The basic type used for binary data read from or written to a file is\n"
+ "bytes. bytearrays are accepted too, and in some cases (such as\n"
+ "readinto) needed. Text I/O classes work with str data.\n"
+ "\n"
+ "Note that calling any method (even inquiries) on a closed stream is\n"
+ "undefined. Implementations may raise IOError in this case.\n"
+ "\n"
+ "IOBase (and its subclasses) support the iterator protocol, meaning\n"
+ "that an IOBase object can be iterated over yielding the lines in a\n"
+ "stream.\n"
+ "\n"
+ "IOBase also supports the :keyword:`with` statement. In this example,\n"
+ "fp is closed after the suite of the with statment is complete:\n"
+ "\n"
+ "with open('spam.txt', 'r') as fp:\n"
+ " fp.write('Spam and eggs!')\n");
+
+/* Use this macro whenever you want to check the internal `closed` status
+ of the IOBase object rather than the virtual `closed` attribute as returned
+ by whatever subclass. */
+
+#define IS_CLOSED(self) \
+ PyObject_HasAttrString(self, "__IOBase_closed")
+
+/* Internal methods */
+static PyObject *
+IOBase_unsupported(const char *message)
+{
+ PyErr_SetString(IO_STATE->unsupported_operation, message);
+ return NULL;
+}
+
+/* Positionning */
+
+PyDoc_STRVAR(IOBase_seek_doc,
+ "Change stream position.\n"
+ "\n"
+ "Change the stream position to byte offset offset. offset is\n"
+ "interpreted relative to the position indicated by whence. Values\n"
+ "for whence are:\n"
+ "\n"
+ "* 0 -- start of stream (the default); offset should be zero or positive\n"
+ "* 1 -- current stream position; offset may be negative\n"
+ "* 2 -- end of stream; offset is usually negative\n"
+ "\n"
+ "Return the new absolute position.");
+
+static PyObject *
+IOBase_seek(PyObject *self, PyObject *args)
+{
+ return IOBase_unsupported("seek");
+}
+
+PyDoc_STRVAR(IOBase_tell_doc,
+ "Return current stream position.");
+
+static PyObject *
+IOBase_tell(PyObject *self, PyObject *args)
+{
+ return PyObject_CallMethod(self, "seek", "ii", 0, 1);
+}
+
+PyDoc_STRVAR(IOBase_truncate_doc,
+ "Truncate file to size bytes.\n"
+ "\n"
+ "Size defaults to the current IO position as reported by tell(). Return\n"
+ "the new size.");
+
+static PyObject *
+IOBase_truncate(PyObject *self, PyObject *args)
+{
+ return IOBase_unsupported("truncate");
+}
+
+/* Flush and close methods */
+
+PyDoc_STRVAR(IOBase_flush_doc,
+ "Flush write buffers, if applicable.\n"
+ "\n"
+ "This is not implemented for read-only and non-blocking streams.\n");
+
+static PyObject *
+IOBase_flush(PyObject *self, PyObject *args)
+{
+ /* XXX Should this return the number of bytes written??? */
+ if (IS_CLOSED(self)) {
+ PyErr_SetString(PyExc_ValueError, "I/O operation on closed file.");
+ return NULL;
+ }
+ Py_RETURN_NONE;
+}
+
+PyDoc_STRVAR(IOBase_close_doc,
+ "Flush and close the IO object.\n"
+ "\n"
+ "This method has no effect if the file is already closed.\n");
+
+static int
+IOBase_closed(PyObject *self)
+{
+ PyObject *res;
+ int closed;
+ /* This gets the derived attribute, which is *not* __IOBase_closed
+ in most cases! */
+ res = PyObject_GetAttr(self, _PyIO_str_closed);
+ if (res == NULL)
+ return 0;
+ closed = PyObject_IsTrue(res);
+ Py_DECREF(res);
+ return closed;
+}
+
+static PyObject *
+IOBase_closed_get(PyObject *self, void *context)
+{
+ return PyBool_FromLong(IS_CLOSED(self));
+}
+
+PyObject *
+_PyIOBase_checkClosed(PyObject *self, PyObject *args)
+{
+ if (IOBase_closed(self)) {
+ PyErr_SetString(PyExc_ValueError, "I/O operation on closed file.");
+ return NULL;
+ }
+ if (args == Py_True)
+ return Py_None;
+ else
+ Py_RETURN_NONE;
+}
+
+/* XXX: IOBase thinks it has to maintain its own internal state in
+ `__IOBase_closed` and call flush() by itself, but it is redundant with
+ whatever behaviour a non-trivial derived class will implement. */
+
+static PyObject *
+IOBase_close(PyObject *self, PyObject *args)
+{
+ PyObject *res;
+
+ if (IS_CLOSED(self))
+ Py_RETURN_NONE;
+
+ res = PyObject_CallMethodObjArgs(self, _PyIO_str_flush, NULL);
+ PyObject_SetAttrString(self, "__IOBase_closed", Py_True);
+ if (res == NULL) {
+ /* If flush() fails, just give up */
+ if (PyErr_ExceptionMatches(PyExc_IOError))
+ PyErr_Clear();
+ else
+ return NULL;
+ }
+ Py_XDECREF(res);
+ Py_RETURN_NONE;
+}
+
+/* Finalization and garbage collection support */
+
+int
+_PyIOBase_finalize(PyObject *self)
+{
+ PyObject *res;
+ PyObject *tp, *v, *tb;
+ int closed = 1;
+ int is_zombie;
+
+ /* If _PyIOBase_finalize() is called from a destructor, we need to
+ resurrect the object as calling close() can invoke arbitrary code. */
+ is_zombie = (Py_REFCNT(self) == 0);
+ if (is_zombie) {
+ ++Py_REFCNT(self);
+ }
+ PyErr_Fetch(&tp, &v, &tb);
+ /* If `closed` doesn't exist or can't be evaluated as bool, then the
+ object is probably in an unusable state, so ignore. */
+ res = PyObject_GetAttr(self, _PyIO_str_closed);
+ if (res == NULL)
+ PyErr_Clear();
+ else {
+ closed = PyObject_IsTrue(res);
+ Py_DECREF(res);
+ if (closed == -1)
+ PyErr_Clear();
+ }
+ if (closed == 0) {
+ res = PyObject_CallMethodObjArgs((PyObject *) self, _PyIO_str_close,
+ NULL);
+ /* Silencing I/O errors is bad, but printing spurious tracebacks is
+ equally as bad, and potentially more frequent (because of
+ shutdown issues). */
+ if (res == NULL)
+ PyErr_Clear();
+ else
+ Py_DECREF(res);
+ }
+ PyErr_Restore(tp, v, tb);
+ if (is_zombie) {
+ if (--Py_REFCNT(self) != 0) {
+ /* The object lives again. The following code is taken from
+ slot_tp_del in typeobject.c. */
+ Py_ssize_t refcnt = Py_REFCNT(self);
+ _Py_NewReference(self);
+ Py_REFCNT(self) = refcnt;
+ /* If Py_REF_DEBUG, _Py_NewReference bumped _Py_RefTotal, so
+ * we need to undo that. */
+ _Py_DEC_REFTOTAL;
+ /* If Py_TRACE_REFS, _Py_NewReference re-added self to the object
+ * chain, so no more to do there.
+ * If COUNT_ALLOCS, the original decref bumped tp_frees, and
+ * _Py_NewReference bumped tp_allocs: both of those need to be
+ * undone.
+ */
+#ifdef COUNT_ALLOCS
+ --Py_TYPE(self)->tp_frees;
+ --Py_TYPE(self)->tp_allocs;
+#endif
+ return -1;
+ }
+ }
+ return 0;
+}
+
+static int
+IOBase_traverse(IOBaseObject *self, visitproc visit, void *arg)
+{
+ Py_VISIT(self->dict);
+ return 0;
+}
+
+static int
+IOBase_clear(IOBaseObject *self)
+{
+ if (_PyIOBase_finalize((PyObject *) self) < 0)
+ return -1;
+ Py_CLEAR(self->dict);
+ return 0;
+}
+
+/* Destructor */
+
+static void
+IOBase_dealloc(IOBaseObject *self)
+{
+ /* NOTE: since IOBaseObject has its own dict, Python-defined attributes
+ are still available here for close() to use.
+ However, if the derived class declares a __slots__, those slots are
+ already gone.
+ */
+ if (_PyIOBase_finalize((PyObject *) self) < 0) {
+ /* When called from a heap type's dealloc, the type will be
+ decref'ed on return (see e.g. subtype_dealloc in typeobject.c). */
+ if (PyType_HasFeature(Py_TYPE(self), Py_TPFLAGS_HEAPTYPE))
+ Py_INCREF(Py_TYPE(self));
+ return;
+ }
+ _PyObject_GC_UNTRACK(self);
+ if (self->weakreflist != NULL)
+ PyObject_ClearWeakRefs((PyObject *) self);
+ Py_CLEAR(self->dict);
+ Py_TYPE(self)->tp_free((PyObject *) self);
+}
+
+/* Inquiry methods */
+
+PyDoc_STRVAR(IOBase_seekable_doc,
+ "Return whether object supports random access.\n"
+ "\n"
+ "If False, seek(), tell() and truncate() will raise IOError.\n"
+ "This method may need to do a test seek().");
+
+static PyObject *
+IOBase_seekable(PyObject *self, PyObject *args)
+{
+ Py_RETURN_FALSE;
+}
+
+PyObject *
+_PyIOBase_checkSeekable(PyObject *self, PyObject *args)
+{
+ PyObject *res = PyObject_CallMethodObjArgs(self, _PyIO_str_seekable, NULL);
+ if (res == NULL)
+ return NULL;
+ if (res != Py_True) {
+ Py_CLEAR(res);
+ PyErr_SetString(PyExc_IOError, "File or stream is not seekable.");
+ return NULL;
+ }
+ if (args == Py_True) {
+ Py_DECREF(res);
+ }
+ return res;
+}
+
+PyDoc_STRVAR(IOBase_readable_doc,
+ "Return whether object was opened for reading.\n"
+ "\n"
+ "If False, read() will raise IOError.");
+
+static PyObject *
+IOBase_readable(PyObject *self, PyObject *args)
+{
+ Py_RETURN_FALSE;
+}
+
+/* May be called with any object */
+PyObject *
+_PyIOBase_checkReadable(PyObject *self, PyObject *args)
+{
+ PyObject *res = PyObject_CallMethodObjArgs(self, _PyIO_str_readable, NULL);
+ if (res == NULL)
+ return NULL;
+ if (res != Py_True) {
+ Py_CLEAR(res);
+ PyErr_SetString(PyExc_IOError, "File or stream is not readable.");
+ return NULL;
+ }
+ if (args == Py_True) {
+ Py_DECREF(res);
+ }
+ return res;
+}
+
+PyDoc_STRVAR(IOBase_writable_doc,
+ "Return whether object was opened for writing.\n"
+ "\n"
+ "If False, read() will raise IOError.");
+
+static PyObject *
+IOBase_writable(PyObject *self, PyObject *args)
+{
+ Py_RETURN_FALSE;
+}
+
+/* May be called with any object */
+PyObject *
+_PyIOBase_checkWritable(PyObject *self, PyObject *args)
+{
+ PyObject *res = PyObject_CallMethodObjArgs(self, _PyIO_str_writable, NULL);
+ if (res == NULL)
+ return NULL;
+ if (res != Py_True) {
+ Py_CLEAR(res);
+ PyErr_SetString(PyExc_IOError, "File or stream is not writable.");
+ return NULL;
+ }
+ if (args == Py_True) {
+ Py_DECREF(res);
+ }
+ return res;
+}
+
+/* Context manager */
+
+static PyObject *
+IOBase_enter(PyObject *self, PyObject *args)
+{
+ if (_PyIOBase_checkClosed(self, Py_True) == NULL)
+ return NULL;
+
+ Py_INCREF(self);
+ return self;
+}
+
+static PyObject *
+IOBase_exit(PyObject *self, PyObject *args)
+{
+ return PyObject_CallMethodObjArgs(self, _PyIO_str_close, NULL);
+}
+
+/* Lower-level APIs */
+
+/* XXX Should these be present even if unimplemented? */
+
+PyDoc_STRVAR(IOBase_fileno_doc,
+ "Returns underlying file descriptor if one exists.\n"
+ "\n"
+ "An IOError is raised if the IO object does not use a file descriptor.\n");
+
+static PyObject *
+IOBase_fileno(PyObject *self, PyObject *args)
+{
+ return IOBase_unsupported("fileno");
+}
+
+PyDoc_STRVAR(IOBase_isatty_doc,
+ "Return whether this is an 'interactive' stream.\n"
+ "\n"
+ "Return False if it can't be determined.\n");
+
+static PyObject *
+IOBase_isatty(PyObject *self, PyObject *args)
+{
+ if (_PyIOBase_checkClosed(self, Py_True) == NULL)
+ return NULL;
+ Py_RETURN_FALSE;
+}
+
+/* Readline(s) and writelines */
+
+PyDoc_STRVAR(IOBase_readline_doc,
+ "Read and return a line from the stream.\n"
+ "\n"
+ "If limit is specified, at most limit bytes will be read.\n"
+ "\n"
+ "The line terminator is always b'\n' for binary files; for text\n"
+ "files, the newlines argument to open can be used to select the line\n"
+ "terminator(s) recognized.\n");
+
+static PyObject *
+IOBase_readline(PyObject *self, PyObject *args)
+{
+ /* For backwards compatibility, a (slowish) readline(). */
+
+ Py_ssize_t limit = -1;
+ int has_peek = 0;
+ PyObject *buffer, *result;
+ Py_ssize_t old_size = -1;
+
+ if (!PyArg_ParseTuple(args, "|n:readline", &limit)) {
+ return NULL;
+ }
+
+ if (PyObject_HasAttrString(self, "peek"))
+ has_peek = 1;
+
+ buffer = PyByteArray_FromStringAndSize(NULL, 0);
+ if (buffer == NULL)
+ return NULL;
+
+ while (limit < 0 || Py_SIZE(buffer) < limit) {
+ Py_ssize_t nreadahead = 1;
+ PyObject *b;
+
+ if (has_peek) {
+ PyObject *readahead = PyObject_CallMethod(self, "peek", "i", 1);
+ if (readahead == NULL)
+ goto fail;
+ if (!PyBytes_Check(readahead)) {
+ PyErr_Format(PyExc_IOError,
+ "peek() should have returned a bytes object, "
+ "not '%.200s'", Py_TYPE(readahead)->tp_name);
+ Py_DECREF(readahead);
+ goto fail;
+ }
+ if (PyBytes_GET_SIZE(readahead) > 0) {
+ Py_ssize_t n = 0;
+ const char *buf = PyBytes_AS_STRING(readahead);
+ if (limit >= 0) {
+ do {
+ if (n >= PyBytes_GET_SIZE(readahead) || n >= limit)
+ break;
+ if (buf[n++] == '\n')
+ break;
+ } while (1);
+ }
+ else {
+ do {
+ if (n >= PyBytes_GET_SIZE(readahead))
+ break;
+ if (buf[n++] == '\n')
+ break;
+ } while (1);
+ }
+ nreadahead = n;
+ }
+ Py_DECREF(readahead);
+ }
+
+ b = PyObject_CallMethod(self, "read", "n", nreadahead);
+ if (b == NULL)
+ goto fail;
+ if (!PyBytes_Check(b)) {
+ PyErr_Format(PyExc_IOError,
+ "read() should have returned a bytes object, "
+ "not '%.200s'", Py_TYPE(b)->tp_name);
+ Py_DECREF(b);
+ goto fail;
+ }
+ if (PyBytes_GET_SIZE(b) == 0) {
+ Py_DECREF(b);
+ break;
+ }
+
+ old_size = PyByteArray_GET_SIZE(buffer);
+ PyByteArray_Resize(buffer, old_size + PyBytes_GET_SIZE(b));
+ memcpy(PyByteArray_AS_STRING(buffer) + old_size,
+ PyBytes_AS_STRING(b), PyBytes_GET_SIZE(b));
+
+ Py_DECREF(b);
+
+ if (PyByteArray_AS_STRING(buffer)[PyByteArray_GET_SIZE(buffer) - 1] == '\n')
+ break;
+ }
+
+ result = PyBytes_FromStringAndSize(PyByteArray_AS_STRING(buffer),
+ PyByteArray_GET_SIZE(buffer));
+ Py_DECREF(buffer);
+ return result;
+ fail:
+ Py_DECREF(buffer);
+ return NULL;
+}
+
+static PyObject *
+IOBase_iter(PyObject *self)
+{
+ if (_PyIOBase_checkClosed(self, Py_True) == NULL)
+ return NULL;
+
+ Py_INCREF(self);
+ return self;
+}
+
+static PyObject *
+IOBase_iternext(PyObject *self)
+{
+ PyObject *line = PyObject_CallMethodObjArgs(self, _PyIO_str_readline, NULL);
+
+ if (line == NULL)
+ return NULL;
+
+ if (PyObject_Size(line) == 0) {
+ Py_DECREF(line);
+ return NULL;
+ }
+
+ return line;
+}
+
+PyDoc_STRVAR(IOBase_readlines_doc,
+ "Return a list of lines from the stream.\n"
+ "\n"
+ "hint can be specified to control the number of lines read: no more\n"
+ "lines will be read if the total size (in bytes/characters) of all\n"
+ "lines so far exceeds hint.");
+
+static PyObject *
+IOBase_readlines(PyObject *self, PyObject *args)
+{
+ Py_ssize_t hint = -1, length = 0;
+ PyObject *hintobj = Py_None, *result;
+
+ if (!PyArg_ParseTuple(args, "|O:readlines", &hintobj)) {
+ return NULL;
+ }
+ if (hintobj != Py_None) {
+ hint = PyNumber_AsSsize_t(hintobj, PyExc_ValueError);
+ if (hint == -1 && PyErr_Occurred())
+ return NULL;
+ }
+
+ result = PyList_New(0);
+ if (result == NULL)
+ return NULL;
+
+ if (hint <= 0) {
+ /* XXX special-casing this made sense in the Python version in order
+ to remove the bytecode interpretation overhead, but it could
+ probably be removed here. */
+ PyObject *ret = PyObject_CallMethod(result, "extend", "O", self);
+ if (ret == NULL) {
+ Py_DECREF(result);
+ return NULL;
+ }
+ Py_DECREF(ret);
+ return result;
+ }
+
+ while (1) {
+ PyObject *line = PyIter_Next(self);
+ if (line == NULL) {
+ if (PyErr_Occurred()) {
+ Py_DECREF(result);
+ return NULL;
+ }
+ else
+ break; /* StopIteration raised */
+ }
+
+ if (PyList_Append(result, line) < 0) {
+ Py_DECREF(line);
+ Py_DECREF(result);
+ return NULL;
+ }
+ length += PyObject_Size(line);
+ Py_DECREF(line);
+
+ if (length > hint)
+ break;
+ }
+ return result;
+}
+
+static PyObject *
+IOBase_writelines(PyObject *self, PyObject *args)
+{
+ PyObject *lines, *iter, *res;
+
+ if (!PyArg_ParseTuple(args, "O:writelines", &lines)) {
+ return NULL;
+ }
+
+ if (_PyIOBase_checkClosed(self, Py_True) == NULL)
+ return NULL;
+
+ iter = PyObject_GetIter(lines);
+ if (iter == NULL)
+ return NULL;
+
+ while (1) {
+ PyObject *line = PyIter_Next(iter);
+ if (line == NULL) {
+ if (PyErr_Occurred()) {
+ Py_DECREF(iter);
+ return NULL;
+ }
+ else
+ break; /* Stop Iteration */
+ }
+
+ res = PyObject_CallMethodObjArgs(self, _PyIO_str_write, line, NULL);
+ Py_DECREF(line);
+ if (res == NULL) {
+ Py_DECREF(iter);
+ return NULL;
+ }
+ Py_DECREF(res);
+ }
+ Py_DECREF(iter);
+ Py_RETURN_NONE;
+}
+
+static PyMethodDef IOBase_methods[] = {
+ {"seek", IOBase_seek, METH_VARARGS, IOBase_seek_doc},
+ {"tell", IOBase_tell, METH_NOARGS, IOBase_tell_doc},
+ {"truncate", IOBase_truncate, METH_VARARGS, IOBase_truncate_doc},
+ {"flush", IOBase_flush, METH_NOARGS, IOBase_flush_doc},
+ {"close", IOBase_close, METH_NOARGS, IOBase_close_doc},
+
+ {"seekable", IOBase_seekable, METH_NOARGS, IOBase_seekable_doc},
+ {"readable", IOBase_readable, METH_NOARGS, IOBase_readable_doc},
+ {"writable", IOBase_writable, METH_NOARGS, IOBase_writable_doc},
+
+ {"_checkClosed", _PyIOBase_checkClosed, METH_NOARGS},
+ {"_checkSeekable", _PyIOBase_checkSeekable, METH_NOARGS},
+ {"_checkReadable", _PyIOBase_checkReadable, METH_NOARGS},
+ {"_checkWritable", _PyIOBase_checkWritable, METH_NOARGS},
+
+ {"fileno", IOBase_fileno, METH_NOARGS, IOBase_fileno_doc},
+ {"isatty", IOBase_isatty, METH_NOARGS, IOBase_isatty_doc},
+
+ {"__enter__", IOBase_enter, METH_NOARGS},
+ {"__exit__", IOBase_exit, METH_VARARGS},
+
+ {"readline", IOBase_readline, METH_VARARGS, IOBase_readline_doc},
+ {"readlines", IOBase_readlines, METH_VARARGS, IOBase_readlines_doc},
+ {"writelines", IOBase_writelines, METH_VARARGS},
+
+ {NULL, NULL}
+};
+
+static PyGetSetDef IOBase_getset[] = {
+ {"closed", (getter)IOBase_closed_get, NULL, NULL},
+ {0}
+};
+
+
+PyTypeObject PyIOBase_Type = {
+ PyVarObject_HEAD_INIT(NULL, 0)
+ "_io._IOBase", /*tp_name*/
+ sizeof(IOBaseObject), /*tp_basicsize*/
+ 0, /*tp_itemsize*/
+ (destructor)IOBase_dealloc, /*tp_dealloc*/
+ 0, /*tp_print*/
+ 0, /*tp_getattr*/
+ 0, /*tp_setattr*/
+ 0, /*tp_compare */
+ 0, /*tp_repr*/
+ 0, /*tp_as_number*/
+ 0, /*tp_as_sequence*/
+ 0, /*tp_as_mapping*/
+ 0, /*tp_hash */
+ 0, /*tp_call*/
+ 0, /*tp_str*/
+ 0, /*tp_getattro*/
+ 0, /*tp_setattro*/
+ 0, /*tp_as_buffer*/
+ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE
+ | Py_TPFLAGS_HAVE_GC, /*tp_flags*/
+ IOBase_doc, /* tp_doc */
+ (traverseproc)IOBase_traverse, /* tp_traverse */
+ (inquiry)IOBase_clear, /* tp_clear */
+ 0, /* tp_richcompare */
+ offsetof(IOBaseObject, weakreflist), /* tp_weaklistoffset */
+ IOBase_iter, /* tp_iter */
+ IOBase_iternext, /* tp_iternext */
+ IOBase_methods, /* tp_methods */
+ 0, /* tp_members */
+ IOBase_getset, /* tp_getset */
+ 0, /* tp_base */
+ 0, /* tp_dict */
+ 0, /* tp_descr_get */
+ 0, /* tp_descr_set */
+ offsetof(IOBaseObject, dict), /* tp_dictoffset */
+ 0, /* tp_init */
+ 0, /* tp_alloc */
+ PyType_GenericNew, /* tp_new */
+};
+
+
+/*
+ * RawIOBase class, Inherits from IOBase.
+ */
+PyDoc_STRVAR(RawIOBase_doc,
+ "Base class for raw binary I/O.");
+
+/*
+ * The read() method is implemented by calling readinto(); derived classes
+ * that want to support read() only need to implement readinto() as a
+ * primitive operation. In general, readinto() can be more efficient than
+ * read().
+ *
+ * (It would be tempting to also provide an implementation of readinto() in
+ * terms of read(), in case the latter is a more suitable primitive operation,
+ * but that would lead to nasty recursion in case a subclass doesn't implement
+ * either.)
+*/
+
+static PyObject *
+RawIOBase_read(PyObject *self, PyObject *args)
+{
+ Py_ssize_t n = -1;
+ PyObject *b, *res;
+
+ if (!PyArg_ParseTuple(args, "|n:read", &n)) {
+ return NULL;
+ }
+
+ if (n < 0)
+ return PyObject_CallMethod(self, "readall", NULL);
+
+ /* TODO: allocate a bytes object directly instead and manually construct
+ a writable memoryview pointing to it. */
+ b = PyByteArray_FromStringAndSize(NULL, n);
+ if (b == NULL)
+ return NULL;
+
+ res = PyObject_CallMethodObjArgs(self, _PyIO_str_readinto, b, NULL);
+ if (res == NULL) {
+ Py_DECREF(b);
+ return NULL;
+ }
+
+ n = PyNumber_AsSsize_t(res, PyExc_ValueError);
+ Py_DECREF(res);
+ if (n == -1 && PyErr_Occurred()) {
+ Py_DECREF(b);
+ return NULL;
+ }
+
+ res = PyBytes_FromStringAndSize(PyByteArray_AsString(b), n);
+ Py_DECREF(b);
+ return res;
+}
+
+
+PyDoc_STRVAR(RawIOBase_readall_doc,
+ "Read until EOF, using multiple read() call.");
+
+static PyObject *
+RawIOBase_readall(PyObject *self, PyObject *args)
+{
+ PyObject *b = NULL;
+ Py_ssize_t cursize = 0;
+
+ while (1) {
+ Py_ssize_t length;
+ PyObject *data = PyObject_CallMethod(self, "read",
+ "i", DEFAULT_BUFFER_SIZE);
+
+ if (!data) {
+ Py_XDECREF(b);
+ return NULL;
+ }
+
+ if (!PyBytes_Check(data)) {
+ Py_XDECREF(b);
+ Py_DECREF(data);
+ PyErr_SetString(PyExc_TypeError, "read() should return bytes");
+ return NULL;
+ }
+
+ length = Py_SIZE(data);
+
+ if (b == NULL)
+ b = data;
+ else if (length != 0) {
+
+ _PyBytes_Resize(&b, cursize + length);
+ if (b == NULL) {
+ Py_DECREF(data);
+ return NULL;
+ }
+
+ memcpy(PyBytes_AS_STRING(b) + cursize,
+ PyBytes_AS_STRING(data), length);
+ Py_DECREF(data);
+ }
+
+ if (length == 0)
+ break;
+ }
+
+ return b;
+
+}
+
+static PyMethodDef RawIOBase_methods[] = {
+ {"read", RawIOBase_read, METH_VARARGS},
+ {"readall", RawIOBase_readall, METH_NOARGS, RawIOBase_readall_doc},
+ {NULL, NULL}
+};
+
+PyTypeObject PyRawIOBase_Type = {
+ PyVarObject_HEAD_INIT(NULL, 0)
+ "_io._RawIOBase", /*tp_name*/
+ 0, /*tp_basicsize*/
+ 0, /*tp_itemsize*/
+ 0, /*tp_dealloc*/
+ 0, /*tp_print*/
+ 0, /*tp_getattr*/
+ 0, /*tp_setattr*/
+ 0, /*tp_compare */
+ 0, /*tp_repr*/
+ 0, /*tp_as_number*/
+ 0, /*tp_as_sequence*/
+ 0, /*tp_as_mapping*/
+ 0, /*tp_hash */
+ 0, /*tp_call*/
+ 0, /*tp_str*/
+ 0, /*tp_getattro*/
+ 0, /*tp_setattro*/
+ 0, /*tp_as_buffer*/
+ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /*tp_flags*/
+ RawIOBase_doc, /* tp_doc */
+ 0, /* tp_traverse */
+ 0, /* tp_clear */
+ 0, /* tp_richcompare */
+ 0, /* tp_weaklistoffset */
+ 0, /* tp_iter */
+ 0, /* tp_iternext */
+ RawIOBase_methods, /* tp_methods */
+ 0, /* tp_members */
+ 0, /* tp_getset */
+ &PyIOBase_Type, /* tp_base */
+ 0, /* tp_dict */
+ 0, /* tp_descr_get */
+ 0, /* tp_descr_set */
+ 0, /* tp_dictoffset */
+ 0, /* tp_init */
+ 0, /* tp_alloc */
+ 0, /* tp_new */
+};
Modification de propriétés sur Modules/_iobase.c
___________________________________________________________________
Ajouté : svn:keywords
+ Id
Ajouté : svn:eol-style
+ native
Modification de propriétés sur .
___________________________________________________________________
Supprimé : svnmerge-blocked
- /python/trunk:61438,61442,61454,61475,61478,61486,61489,61491-61492,61529,61564,61570,61577,61585,61587,61590,61779,61810,61867,61871,61875,61878-61882,61904,61936-61937,61940,62005-62006,62015,62019-62020,62023,62025-62026,62028,62030,62067,62075,62095,62097,62099,62103,62123,62126,62138,62143,62195,62223,62309-62310,62398,62431,62511,62517-62518,62536,62599,62666,62684,62720,62722,62793,62797,62861,62865,62879,62884,62888,62900,62912,62917,62920,62923,62943,62960,62962,62968,62971,62974,62977,62983,62985-62986,63004,63007-63008,63013,63018,63021,63025,63030,63046,63055,63080,63086,63098,63100,63105,63108,63114,63129,63134,63145,63149-63150,63153-63154,63166,63177-63180,63187,63191,63195,63207,63210,63213,63218,63225,63228,63233,63236,63240,63242,63249,63255,63260,63262,63265,63268,63271,63274,63277,63279,63282,63285,63288,63291,63294,63297,63300,63303,63306,63308,63315,63323,63326,63336,63343,63347,63354,63358,63374,63376,63381-63382,63384,63392,63403,63408-63410,63413-63415,63421-63422,63425-63426,63428,63430,63434,63440,63458,63469,63481,63485-63491,63493-63495,63498,63513,63528,63537,63545,63547,63549,63568,63586-63589,63597-63601,63603-63607,63611,63617-63618,63630,63649,63660,63665,63672,63675,63677,63679,63685-63686,63691,63704,63714,63718-63719,63721,63725,63736,63738,63742,63745,63767,63776,63799-63800,63814,63846,63848-63849,63861,63863,63873,63899,63910,63914,63932,63942-63943,63945,63961-63963,63965,63967,63982,64016,64018-64019,64028,64031,64040,64044-64045,64048,64057-64058,64062,64068-64069,64080,64086,64090,64093,64097,64105,64128-64129,64133,64142,64169,64206,64248,64250,64254,64371,64386,64392,64398,64400,64413,64424,64429,64431,64436-64439,64453,64456,64462,64471,64489,64498,64508,64511,64516,64520,64527,64535,64546-64547,64554-64555,64572,64578,64580,64595,64633,64635,64649,64673,64702,64762,64791,64854-64855,64858-64859,64861,64865-64866,64910,64913,64922,64930,64953,64958,64962,64986,65005,65016,65020,65032,65042,65044,65046,65069-65070,65075,65082,65085,65102,65109,65111-65112,65172,65193,65198,65205,65217,65266,65284,65289,65310,65312,65318,65323,65346,65349,65351,65353,65355,65382-65383,65386-65387,65391,65393,65395,65402,65422-65423,65425,65438,65440,65442,65444,65446,65449,65451,65453,65455,65457,65462,65464,65467,65477,65488,65506,65508,65510,65512,65514,65516,65519,65522,65524,65563,65578,65584,65586,65588,65606,65613,65615,65617,65619,65642,65655,65663,65665,65679,65710,65716,65719,65721,65733,65741-65742,65748,65762,65768,65798,65802-65803,65806,65814,65822,65839,65865,65872,65874,65880,65891,65893,65912,65914,65917,65922,65926,65995,66004,66013,66039,66043,66058,66088,66100,66114,66119,66123,66127,66135,66137,66142,66181-66182,66192,66196-66197,66229,66232,66275,66281-66282,66284,66301,66310,66316,66319,66332,66386,66390,66415-66416,66422,66447,66450,66498,66502,66504,66506,66554,66566,66568-66569,66620,66657,66676,66682,66689,66714,66721,66744,66756,66763-66765,66768,66809-66810,66822,66878,67002,67013,67041,67060-67061,67163,67166,67266,67287,67303,67307,67326,67332,67336,67349,67353,67370,67376,67396,67407,67411,67498,67521,67581,67583-67584,67587,67601,67614,67619,67694,67746,67748,67762,67797,67822,67902,67934-67935,67955,67967,67976,67980,68014,68089,68092,68150,68156,68158-68161,68163,68179,68208-68209,68220,68231,68238,68240,68243,68395,68424,68426,68429-68430,68432,68439,68487,68521,68532,68544-68545,68559,68562,68565-68567,68569,68579-68580,68584,68589,68592,68597,68603-68605,68705,68760,68764,68766,68772,68785,68789,68792-68793,68803,68805,68807,68813,68826,68829,68831,68843,68845,68850,68853,68892,68925,68927,68941-68942,68953,68964,68985,68998,69001,69010,69012,69014,69018,69023,69039,69070,69074,69085,69087,69134,69146,69149,69161,69227,69237,69240,69242,69252-69253,69257,69262,69268,69271-69273,69276,69295,69302-69305,69315,69322,69373-69374,69389,69394,69414,69433,69443,69509,69516,69522,69525,69528,69530,69546,69561,69570,69573,69578,69604,69610,69639,69672,69685,69689,69709,69715-69717,69739,69743,69748,69751,69757,69761,69765,69770,69772,69777,69795,69837-69838,69870-69871,69878,69896,69908,69937,69946,69952-69953,69955,69959,69981,69983,69994,70000,70011,70016,70071,70078
Modifié : svnmerge-integrated
- /python/trunk:1-61437,61439-61441,61443-61453,61455-61474,61476-61477,61479-61485,61487-61488,61490,61493-61528,61530-61563,61565-61569,61571-61576,61578-61584,61586,61588-61589,61591-61778,61780-61809,61811-61866,61868-61870,61872-61874,61876-61877,61883-61903,61905-61935,61938-61939,61941-62004,62007-62014,62016-62018,62021-62022,62024,62027,62029,62031-62066,62068-62074,62076-62094,62096,62098,62100-62102,62104-62122,62124-62125,62127-62137,62139-62142,62144-62194,62196-62222,62224-62308,62311-62397,62399-62430,62432-62510,62512-62516,62519-62535,62537-62598,62600-62665,62667-62683,62685-62719,62721,62723-62792,62794-62796,62798-62860,62862-62864,62866-62878,62880-62883,62885-62887,62889-62899,62901-62911,62913-62916,62918-62919,62921-62922,62924-62942,62944-62959,62961,62963-62967,62969-62970,62972-62973,62975-62976,62978-62982,62984,62987-63003,63005-63006,63009-63012,63014-63017,63019-63020,63022-63024,63026-63029,63031-63045,63047-63054,63056-63079,63081-63085,63087-63097,63099,63101-63104,63106-63107,63109-63113,63115-63128,63130-63133,63135-63144,63146-63148,63151-63152,63155-63165,63167-63176,63181-63186,63188-63190,63192-63194,63196-63206,63208-63209,63211-63212,63214-63217,63219-63224,63226-63227,63229-63232,63234-63235,63237-63239,63241,63243-63248,63250-63254,63256-63259,63261,63263-63264,63266-63267,63269-63270,63272-63273,63275-63276,63278,63280-63281,63283-63284,63286-63287,63289-63290,63292-63293,63295-63296,63298-63299,63301-63302,63304-63305,63307,63309-63314,63316-63322,63324-63325,63327-63335,63337-63342,63344-63346,63348-63353,63355-63357,63359-63373,63375,63377-63380,63383,63385-63391,63393-63402,63404-63407,63411-63412,63416-63420,63423-63424,63427,63429,63431-63433,63435-63439,63441-63457,63459-63468,63470-63480,63482-63484,63492,63496-63497,63499-63512,63514-63527,63529-63536,63538-63544,63546,63548,63550-63567,63569-63585,63590-63596,63602,63608-63610,63612-63616,63619-63629,63631-63648,63650-63659,63661-63664,63666-63671,63673-63674,63676,63678,63680-63684,63687-63690,63692-63703,63705-63713,63715-63717,63720,63722-63724,63726-63735,63737,63739-63741,63743-63744,63746-63766,63768-63775,63777-63798,63801-63813,63815-63845,63847,63850-63860,63862,63864-63872,63874-63898,63900-63909,63911-63913,63915-63931,63933-63941,63944,63946-63960,63964,63966,63968-63981,63983-64015,64017,64020-64027,64029-64030,64032-64039,64041-64043,64046-64047,64049-64056,64059-64061,64063-64067,64070-64079,64081-64085,64087-64089,64091-64092,64094-64096,64098-64104,64106-64127,64130-64132,64134-64141,64143-64168,64170-64205,64207-64247,64249,64251-64253,64255-64370,64372-64385,64387-64391,64393-64397,64399,64401-64412,64414-64423,64425-64428,64430,64432-64435,64440-64452,64454-64455,64457-64461,64463-64470,64472-64488,64490-64497,64499-64507,64509-64510,64512-64515,64517-64519,64521-64526,64528-64534,64536-64545,64548-64553,64556-64571,64573-64577,64579,64581-64594,64596-64632,64634,64636-64648,64650-64672,64674-64701,64703-64761,64763-64790,64792-64853,64856-64857,64860,64862-64864,64867-64909,64911-64912,64914-64921,64923-64929,64931-64952,64954-64957,64959-64961,64963-64985,64987-65004,65006-65015,65017-65019,65021-65031,65033-65041,65043,65045,65047-65068,65071-65074,65076-65081,65083-65084,65086-65101,65103-65108,65110,65113-65171,65173-65192,65194-65197,65199-65204,65206-65216,65218-65265,65267-65283,65285-65288,65290-65309,65311,65313-65317,65319-65322,65324-65345,65347-65348,65350,65352,65354,65356-65381,65384-65385,65388-65390,65392,65394,65396-65401,65403-65421,65424,65426-65437,65439,65441,65443,65445,65447-65448,65450,65452,65454,65456,65458-65461,65463,65465-65466,65468-65476,65478-65487,65489-65505,65507,65509,65511,65513,65515,65517-65518,65520-65521,65523,65525-65562,65564-65577,65579-65583,65585,65587,65589-65605,65607-65612,65614,65616,65618,65620-65641,65643-65654,65656-65662,65664,65666-65678,65680-65709,65711-65715,65717-65718,65720,65722-65732,65734-65740,65743-65747,65749-65761,65763-65767,65769-65797,65799-65801,65804-65805,65807-65813,65815-65821,65823-65838,65840-65864,65866-65871,65873,65875-65879,65881-65890,65892,65894-65911,65913,65915-65916,65918-65921,65923-65925,65927-65994,65996-66003,66005-66012,66014-66038,66040-66042,66044-66057,66059-66087,66089-66099,66101-66113,66115-66118,66120-66122,66124-66126,66128-66134,66136,66138-66141,66143-66180,66183-66191,66193-66195,66198-66228,66230-66231,66233-66274,66276-66280,66283,66285-66300,66302-66309,66311-66315,66317-66318,66320-66331,66333-66385,66387-66389,66391-66414,66417-66421,66423-66446,66448-66449,66451-66497,66499-66501,66503,66505,66507-66553,66555-66565,66567,66570-66619,66621-66656,66658-66675,66677-66681,66683-66688,66690-66713,66715-66720,66722-66743,66745-66755,66757-66762,66766-66767,66769-66808,66811-66821,66823-66877,66879-67001,67003-67012,67014-67040,67042-67059,67062-67162,67164-67165,67167-67265,67267-67286,67288-67302,67304-67306,67308-67325,67327-67331,67333-67335,67337-67348,67350-67352,67354-67369,67371-67375,67377-67395,67397-67406,67408-67410,67412-67497,67499-67520,67522-67580,67582,67585-67586,67588-67600,67602-67613,67615-67618,67620-67693,67695-67745,67747,67749-67761,67763-67796,67798-67821,67823-67901,67903-67933,67936-67954,67956-67966,67968-67975,67977-67979,67981-68013,68015-68088,68090-68091,68093-68149,68151-68155,68157,68162,68164-68178,68180-68207,68210-68219,68221-68230,68232-68237,68239,68241-68242,68244-68394,68396-68423,68425,68427-68428,68431,68433-68438,68440-68486,68488-68520,68522-68531,68533-68543,68546-68558,68560-68561,68563-68564,68568,68570-68578,68581-68583,68585-68588,68590-68591,68593-68596,68598-68602,68606-68704,68706-68759,68761-68763,68765,68767-68771,68773-68784,68786-68788,68790-68791,68794-68802,68804,68806,68808-68812,68814-68825,68827-68828,68830,68832-68842,68844,68846-68849,68851-68852,68854-68891,68893-68924,68926,68928-68940,68943-68952,68954-68963,68965-68984,68986-68997,68999-69000,69002-69009,69011,69013,69015-69017,69019-69022,69024-69038,69040-69069,69071-69073,69075-69084,69086,69088-69133,69135-69145,69147-69148,69150-69160,69162-69226,69228-69236,69238-69239,69241,69243-69251,69254-69256,69258-69261,69263-69267,69269-69270,69274-69275,69277-69294,69296-69301,69306-69314,69316-69321,69323-69372,69375-69388,69390-69393,69395-69413,69415-69432,69434-69442,69444-69508,69510-69515,69517-69521,69523-69524,69526-69527,69529,69531-69545,69547-69560,69562-69569,69571-69572,69574-69577,69579-69603,69605-69609,69611-69638,69640-69671,69673-69684,69686-69688,69690-69708,69710-69714,69718-69738,69740-69742,69744-69747,69749-69750,69752-69756,69758-69760,69762-69764,69766-69769,69771,69773-69776,69778-69794,69796-69836,69839-69869,69872-69877,69879-69895,69897-69907,69909-69936,69938-69945,69947-69951,69954,69956-69958,69960-69980,69982,69984-69993,69995,70003,70007,70017,70049,70052,70056,70062,70088,70090,70094,70107
+ /python/branches/py3k:1-70114
« Lib/_pyio.py ('K') | « Modules/_fileio.c ('k') | Modules/_iomodule.h » ('j') | no next file with comments »

Powered by Google App Engine
RSS Feeds Recent Issues | This issue
This is Rietveld f62528b