summaryrefslogtreecommitdiffstats
path: root/Modules
diff options
context:
space:
mode:
authorAntoine Pitrou <solipsis@pitrou.net>2009-03-29 19:19:49 (GMT)
committerAntoine Pitrou <solipsis@pitrou.net>2009-03-29 19:19:49 (GMT)
commit00a9b738179cf1dc96817870c51eda5807ff6888 (patch)
treedf883d3662e38250c1084dd35d906dff000dd2c9 /Modules
parent7d037a7b5285093a4fa9906dc22d3dc1bf508b19 (diff)
downloadcpython-00a9b738179cf1dc96817870c51eda5807ff6888.zip
cpython-00a9b738179cf1dc96817870c51eda5807ff6888.tar.gz
cpython-00a9b738179cf1dc96817870c51eda5807ff6888.tar.bz2
Rewrite IOBase.readall to avoid costly string resizes, and plug a leak
Diffstat (limited to 'Modules')
-rw-r--r--Modules/_bufferedio.c11
-rw-r--r--Modules/_iobase.c48
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[] = {