diff options
author | Antoine Pitrou <solipsis@pitrou.net> | 2009-03-29 19:19:49 (GMT) |
---|---|---|
committer | Antoine Pitrou <solipsis@pitrou.net> | 2009-03-29 19:19:49 (GMT) |
commit | 00a9b738179cf1dc96817870c51eda5807ff6888 (patch) | |
tree | df883d3662e38250c1084dd35d906dff000dd2c9 | |
parent | 7d037a7b5285093a4fa9906dc22d3dc1bf508b19 (diff) | |
download | cpython-00a9b738179cf1dc96817870c51eda5807ff6888.zip cpython-00a9b738179cf1dc96817870c51eda5807ff6888.tar.gz cpython-00a9b738179cf1dc96817870c51eda5807ff6888.tar.bz2 |
Rewrite IOBase.readall to avoid costly string resizes, and plug a leak
-rw-r--r-- | Modules/_bufferedio.c | 11 | ||||
-rw-r--r-- | Modules/_iobase.c | 48 |
2 files changed, 21 insertions, 38 deletions
diff --git a/Modules/_bufferedio.c b/Modules/_bufferedio.c index 01171cd..9960dba 100644 --- a/Modules/_bufferedio.c +++ b/Modules/_bufferedio.c @@ -1144,7 +1144,6 @@ _BufferedReader_read_unlocked(BufferedObject *self, Py_ssize_t n) PyObject *data, *res = NULL; Py_ssize_t current_size, remaining, written; char *out; - static PyObject *sep = NULL; /* Special case for when the number of bytes to read is unspecified. */ if (n == -1) { @@ -1201,15 +1200,7 @@ _BufferedReader_read_unlocked(BufferedObject *self, Py_ssize_t n) return data; } else { - if (sep == NULL) { - sep = PyBytes_FromStringAndSize(NULL, 0); - if (sep == NULL) { - Py_DECREF(data); - Py_DECREF(chunks); - return NULL; - } - } - res =_PyBytes_Join(sep, chunks); + res = _PyBytes_Join(_PyIO_empty_bytes, chunks); Py_DECREF(data); Py_DECREF(chunks); return res; diff --git a/Modules/_iobase.c b/Modules/_iobase.c index b5fef5b..ef6d516 100644 --- a/Modules/_iobase.c +++ b/Modules/_iobase.c @@ -809,49 +809,41 @@ PyDoc_STRVAR(RawIOBase_readall_doc, static PyObject * RawIOBase_readall(PyObject *self, PyObject *args) { - PyObject *b = NULL; - Py_ssize_t cursize = 0; + int r; + PyObject *chunks = PyList_New(0); + PyObject *result; + + if (chunks == NULL) + return NULL; while (1) { - Py_ssize_t length; PyObject *data = PyObject_CallMethod(self, "read", "i", DEFAULT_BUFFER_SIZE); - if (!data) { - Py_XDECREF(b); + Py_DECREF(chunks); return NULL; } - if (!PyBytes_Check(data)) { - Py_XDECREF(b); + Py_DECREF(chunks); 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); + if (PyBytes_GET_SIZE(data) == 0) { + /* EOF */ Py_DECREF(data); - } - - if (length == 0) break; + } + r = PyList_Append(chunks, data); + Py_DECREF(data); + if (r < 0) { + Py_DECREF(chunks); + return NULL; + } } - - return b; - + result = _PyBytes_Join(_PyIO_empty_bytes, chunks); + Py_DECREF(chunks); + return result; } static PyMethodDef RawIOBase_methods[] = { |