Kaydet (Commit) 8dcdb25d authored tarafından Alexandre Vassalotti's avatar Alexandre Vassalotti

Improved bytes_extend() to avoid making a full copy of the temporary

buffer. This also makes the code slightly cleaner.
üst 3071f819
...@@ -2585,7 +2585,7 @@ end of B."); ...@@ -2585,7 +2585,7 @@ end of B.");
static PyObject * static PyObject *
bytes_extend(PyBytesObject *self, PyObject *arg) bytes_extend(PyBytesObject *self, PyObject *arg)
{ {
PyObject *it, *item, *tmp, *res; PyObject *it, *item, *bytes_obj;
Py_ssize_t buf_size = 0, len = 0; Py_ssize_t buf_size = 0, len = 0;
int value; int value;
char *buf; char *buf;
...@@ -2605,40 +2605,46 @@ bytes_extend(PyBytesObject *self, PyObject *arg) ...@@ -2605,40 +2605,46 @@ bytes_extend(PyBytesObject *self, PyObject *arg)
/* Try to determine the length of the argument. 32 is abitrary. */ /* Try to determine the length of the argument. 32 is abitrary. */
buf_size = _PyObject_LengthHint(arg, 32); buf_size = _PyObject_LengthHint(arg, 32);
buf = (char *)PyMem_Malloc(buf_size * sizeof(char)); bytes_obj = PyBytes_FromStringAndSize(NULL, buf_size);
if (buf == NULL) if (bytes_obj == NULL)
return PyErr_NoMemory(); return NULL;
buf = PyBytes_AS_STRING(bytes_obj);
while ((item = PyIter_Next(it)) != NULL) { while ((item = PyIter_Next(it)) != NULL) {
if (! _getbytevalue(item, &value)) { if (! _getbytevalue(item, &value)) {
Py_DECREF(item); Py_DECREF(item);
Py_DECREF(it); Py_DECREF(it);
PyMem_Free(buf); Py_DECREF(bytes_obj);
return NULL; return NULL;
} }
buf[len++] = value; buf[len++] = value;
Py_DECREF(item); Py_DECREF(item);
if (len >= buf_size) { if (len >= buf_size) {
char *new_buf;
buf_size = len + (len >> 1) + 1; buf_size = len + (len >> 1) + 1;
new_buf = (char *)PyMem_Realloc(buf, buf_size * sizeof(char)); if (PyBytes_Resize((PyObject *)bytes_obj, buf_size) < 0) {
if (new_buf == NULL) {
Py_DECREF(it); Py_DECREF(it);
PyMem_Free(buf); Py_DECREF(bytes_obj);
return PyErr_NoMemory(); return NULL;
} }
buf = new_buf; /* Recompute the `buf' pointer, since the resizing operation may
have invalidated it. */
buf = PyBytes_AS_STRING(bytes_obj);
} }
} }
Py_DECREF(it); Py_DECREF(it);
/* XXX: Is possible to avoid a full copy of the buffer? */ /* Resize down to exact size. */
tmp = PyBytes_FromStringAndSize(buf, len); if (PyBytes_Resize((PyObject *)bytes_obj, len) < 0) {
res = bytes_extend(self, tmp); Py_DECREF(bytes_obj);
Py_DECREF(tmp); return NULL;
PyMem_Free(buf); }
return res; if (bytes_setslice(self, Py_SIZE(self), Py_SIZE(self), bytes_obj) == -1)
return NULL;
Py_DECREF(bytes_obj);
Py_RETURN_NONE;
} }
PyDoc_STRVAR(pop__doc__, PyDoc_STRVAR(pop__doc__,
......
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