[Python-checkins] r70694 - in python/branches/py3k/Modules: _bufferedio.c _iobase.c

antoine.pitrou python-checkins at python.org
Sun Mar 29 21:19:50 CEST 2009


Author: antoine.pitrou
Date: Sun Mar 29 21:19:49 2009
New Revision: 70694

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



Modified:
   python/branches/py3k/Modules/_bufferedio.c
   python/branches/py3k/Modules/_iobase.c

Modified: python/branches/py3k/Modules/_bufferedio.c
==============================================================================
--- python/branches/py3k/Modules/_bufferedio.c	(original)
+++ python/branches/py3k/Modules/_bufferedio.c	Sun Mar 29 21:19:49 2009
@@ -1144,7 +1144,6 @@
     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 @@
                     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;

Modified: python/branches/py3k/Modules/_iobase.c
==============================================================================
--- python/branches/py3k/Modules/_iobase.c	(original)
+++ python/branches/py3k/Modules/_iobase.c	Sun Mar 29 21:19:49 2009
@@ -809,49 +809,41 @@
 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[] = {


More information about the Python-checkins mailing list