mirror of
https://github.com/python/cpython.git
synced 2025-08-03 16:39:00 +00:00
Move in-place Unicode append to its own subfunction
This commit is contained in:
parent
a5f9163501
commit
b092365cc6
1 changed files with 54 additions and 38 deletions
|
@ -9967,6 +9967,54 @@ PyUnicode_Concat(PyObject *left, PyObject *right)
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
unicode_append_inplace(PyObject **p_left, PyObject *right)
|
||||||
|
{
|
||||||
|
Py_ssize_t left_len, right_len, new_len;
|
||||||
|
#ifdef Py_DEBUG
|
||||||
|
Py_ssize_t copied;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
assert(PyUnicode_IS_READY(*p_left));
|
||||||
|
assert(PyUnicode_IS_READY(right));
|
||||||
|
|
||||||
|
left_len = PyUnicode_GET_LENGTH(*p_left);
|
||||||
|
right_len = PyUnicode_GET_LENGTH(right);
|
||||||
|
if (left_len > PY_SSIZE_T_MAX - right_len) {
|
||||||
|
PyErr_SetString(PyExc_OverflowError,
|
||||||
|
"strings are too large to concat");
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
new_len = left_len + right_len;
|
||||||
|
|
||||||
|
/* Now we own the last reference to 'left', so we can resize it
|
||||||
|
* in-place.
|
||||||
|
*/
|
||||||
|
if (unicode_resize(p_left, new_len) != 0) {
|
||||||
|
/* XXX if _PyUnicode_Resize() fails, 'left' has been
|
||||||
|
* deallocated so it cannot be put back into
|
||||||
|
* 'variable'. The MemoryError is raised when there
|
||||||
|
* is no value in 'variable', which might (very
|
||||||
|
* remotely) be a cause of incompatibilities.
|
||||||
|
*/
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
/* copy 'right' into the newly allocated area of 'left' */
|
||||||
|
#ifdef Py_DEBUG
|
||||||
|
copied = PyUnicode_CopyCharacters(*p_left, left_len,
|
||||||
|
right, 0,
|
||||||
|
right_len);
|
||||||
|
assert(0 <= copied);
|
||||||
|
#else
|
||||||
|
PyUnicode_CopyCharacters(*p_left, left_len, right, 0, right_len);
|
||||||
|
#endif
|
||||||
|
return;
|
||||||
|
|
||||||
|
error:
|
||||||
|
Py_DECREF(*p_left);
|
||||||
|
*p_left = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
PyUnicode_Append(PyObject **p_left, PyObject *right)
|
PyUnicode_Append(PyObject **p_left, PyObject *right)
|
||||||
{
|
{
|
||||||
|
@ -9990,50 +10038,18 @@ PyUnicode_Append(PyObject **p_left, PyObject *right)
|
||||||
&& (_PyUnicode_KIND(right) <= _PyUnicode_KIND(left)
|
&& (_PyUnicode_KIND(right) <= _PyUnicode_KIND(left)
|
||||||
|| _PyUnicode_WSTR(left) != NULL))
|
|| _PyUnicode_WSTR(left) != NULL))
|
||||||
{
|
{
|
||||||
Py_ssize_t left_len, right_len, new_len;
|
|
||||||
#ifdef Py_DEBUG
|
|
||||||
Py_ssize_t copied;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
if (PyUnicode_READY(left))
|
if (PyUnicode_READY(left))
|
||||||
goto error;
|
goto error;
|
||||||
if (PyUnicode_READY(right))
|
if (PyUnicode_READY(right))
|
||||||
goto error;
|
goto error;
|
||||||
|
|
||||||
/* FIXME: support ascii+latin1, PyASCIIObject => PyCompactUnicodeObject */
|
/* Don't resize for ascii += latin1. Convert ascii to latin1 requires
|
||||||
if (PyUnicode_MAX_CHAR_VALUE(right) <= PyUnicode_MAX_CHAR_VALUE(left))
|
to change the structure size, but characters are stored just after
|
||||||
|
the structure, and so it requires to move all charactres which is
|
||||||
|
not so different than duplicating the string. */
|
||||||
|
if (!(PyUnicode_IS_ASCII(left) && !PyUnicode_IS_ASCII(right)))
|
||||||
{
|
{
|
||||||
left_len = PyUnicode_GET_LENGTH(left);
|
unicode_append_inplace(p_left, right);
|
||||||
right_len = PyUnicode_GET_LENGTH(right);
|
|
||||||
if (left_len > PY_SSIZE_T_MAX - right_len) {
|
|
||||||
PyErr_SetString(PyExc_OverflowError,
|
|
||||||
"strings are too large to concat");
|
|
||||||
goto error;
|
|
||||||
}
|
|
||||||
new_len = left_len + right_len;
|
|
||||||
|
|
||||||
/* Now we own the last reference to 'left', so we can resize it
|
|
||||||
* in-place.
|
|
||||||
*/
|
|
||||||
if (unicode_resize(&left, new_len) != 0) {
|
|
||||||
/* XXX if _PyUnicode_Resize() fails, 'left' has been
|
|
||||||
* deallocated so it cannot be put back into
|
|
||||||
* 'variable'. The MemoryError is raised when there
|
|
||||||
* is no value in 'variable', which might (very
|
|
||||||
* remotely) be a cause of incompatibilities.
|
|
||||||
*/
|
|
||||||
goto error;
|
|
||||||
}
|
|
||||||
/* copy 'right' into the newly allocated area of 'left' */
|
|
||||||
#ifdef Py_DEBUG
|
|
||||||
copied = PyUnicode_CopyCharacters(left, left_len,
|
|
||||||
right, 0,
|
|
||||||
right_len);
|
|
||||||
assert(0 <= copied);
|
|
||||||
#else
|
|
||||||
PyUnicode_CopyCharacters(left, left_len, right, 0, right_len);
|
|
||||||
#endif
|
|
||||||
*p_left = left;
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue