]> granicus.if.org Git - python/commitdiff
Rewrite IOBase.readall to avoid costly string resizes, and plug a leak
authorAntoine Pitrou <solipsis@pitrou.net>
Sun, 29 Mar 2009 19:19:49 +0000 (19:19 +0000)
committerAntoine Pitrou <solipsis@pitrou.net>
Sun, 29 Mar 2009 19:19:49 +0000 (19:19 +0000)
Modules/_bufferedio.c
Modules/_iobase.c

index 01171cdc6a9db9402dbaee5979d264aface340a8..9960dba4a4971872d5fe83233a8d5082de21fca9 100644 (file)
@@ -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;
index b5fef5bc77f9c4be47242e6de3388e5d0b7a76cc..ef6d516d19cc246917bb38aeb914785d6173eb77 100644 (file)
@@ -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[] = {