Commit 00a9b738 authored by Antoine Pitrou's avatar Antoine Pitrou

Rewrite IOBase.readall to avoid costly string resizes, and plug a leak

parent 7d037a7b
...@@ -1144,7 +1144,6 @@ _BufferedReader_read_unlocked(BufferedObject *self, Py_ssize_t n) ...@@ -1144,7 +1144,6 @@ _BufferedReader_read_unlocked(BufferedObject *self, Py_ssize_t n)
PyObject *data, *res = NULL; PyObject *data, *res = NULL;
Py_ssize_t current_size, remaining, written; Py_ssize_t current_size, remaining, written;
char *out; char *out;
static PyObject *sep = NULL;
/* Special case for when the number of bytes to read is unspecified. */ /* Special case for when the number of bytes to read is unspecified. */
if (n == -1) { if (n == -1) {
...@@ -1201,15 +1200,7 @@ _BufferedReader_read_unlocked(BufferedObject *self, Py_ssize_t n) ...@@ -1201,15 +1200,7 @@ _BufferedReader_read_unlocked(BufferedObject *self, Py_ssize_t n)
return data; return data;
} }
else { else {
if (sep == NULL) { res = _PyBytes_Join(_PyIO_empty_bytes, chunks);
sep = PyBytes_FromStringAndSize(NULL, 0);
if (sep == NULL) {
Py_DECREF(data);
Py_DECREF(chunks);
return NULL;
}
}
res =_PyBytes_Join(sep, chunks);
Py_DECREF(data); Py_DECREF(data);
Py_DECREF(chunks); Py_DECREF(chunks);
return res; return res;
......
...@@ -809,49 +809,41 @@ PyDoc_STRVAR(RawIOBase_readall_doc, ...@@ -809,49 +809,41 @@ PyDoc_STRVAR(RawIOBase_readall_doc,
static PyObject * static PyObject *
RawIOBase_readall(PyObject *self, PyObject *args) RawIOBase_readall(PyObject *self, PyObject *args)
{ {
PyObject *b = NULL; int r;
Py_ssize_t cursize = 0; PyObject *chunks = PyList_New(0);
PyObject *result;
if (chunks == NULL)
return NULL;
while (1) { while (1) {
Py_ssize_t length;
PyObject *data = PyObject_CallMethod(self, "read", PyObject *data = PyObject_CallMethod(self, "read",
"i", DEFAULT_BUFFER_SIZE); "i", DEFAULT_BUFFER_SIZE);
if (!data) { if (!data) {
Py_XDECREF(b); Py_DECREF(chunks);
return NULL; return NULL;
} }
if (!PyBytes_Check(data)) { if (!PyBytes_Check(data)) {
Py_XDECREF(b); Py_DECREF(chunks);
Py_DECREF(data); Py_DECREF(data);
PyErr_SetString(PyExc_TypeError, "read() should return bytes"); PyErr_SetString(PyExc_TypeError, "read() should return bytes");
return NULL; return NULL;
} }
if (PyBytes_GET_SIZE(data) == 0) {
length = Py_SIZE(data); /* EOF */
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); Py_DECREF(data);
}
if (length == 0)
break; break;
}
r = PyList_Append(chunks, data);
Py_DECREF(data);
if (r < 0) {
Py_DECREF(chunks);
return NULL;
}
} }
result = _PyBytes_Join(_PyIO_empty_bytes, chunks);
return b; Py_DECREF(chunks);
return result;
} }
static PyMethodDef RawIOBase_methods[] = { static PyMethodDef RawIOBase_methods[] = {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment