resize_copy() now supports legacy ready strings

This commit is contained in:
Victor Stinner 2011-12-12 00:13:42 +01:00
parent 488fa49acf
commit 7a9105a380
2 changed files with 19 additions and 13 deletions

View File

@ -220,6 +220,7 @@ typedef struct {
- compact ascii: - compact ascii:
* structure = PyASCIIObject * structure = PyASCIIObject
* test: PyUnicode_IS_COMPACT_ASCII(op)
* kind = PyUnicode_1BYTE_KIND * kind = PyUnicode_1BYTE_KIND
* compact = 1 * compact = 1
* ascii = 1 * ascii = 1
@ -231,6 +232,7 @@ typedef struct {
- compact: - compact:
* structure = PyCompactUnicodeObject * structure = PyCompactUnicodeObject
* test: PyUnicode_IS_ASCII(op) && !PyUnicode_IS_COMPACT(op)
* kind = PyUnicode_1BYTE_KIND, PyUnicode_2BYTE_KIND or * kind = PyUnicode_1BYTE_KIND, PyUnicode_2BYTE_KIND or
PyUnicode_4BYTE_KIND PyUnicode_4BYTE_KIND
* compact = 1 * compact = 1
@ -247,6 +249,7 @@ typedef struct {
- legacy string, not ready: - legacy string, not ready:
* structure = PyUnicodeObject * structure = PyUnicodeObject
* test: kind == PyUnicode_WCHAR_KIND
* length = 0 (use wstr_length) * length = 0 (use wstr_length)
* hash = -1 * hash = -1
* kind = PyUnicode_WCHAR_KIND * kind = PyUnicode_WCHAR_KIND
@ -262,6 +265,7 @@ typedef struct {
- legacy string, ready: - legacy string, ready:
* structure = PyUnicodeObject structure * structure = PyUnicodeObject structure
* test: !PyUnicode_IS_COMPACT(op) && kind != PyUnicode_WCHAR_KIND
* kind = PyUnicode_1BYTE_KIND, PyUnicode_2BYTE_KIND or * kind = PyUnicode_1BYTE_KIND, PyUnicode_2BYTE_KIND or
PyUnicode_4BYTE_KIND PyUnicode_4BYTE_KIND
* compact = 0 * compact = 0

View File

@ -688,26 +688,19 @@ static int
resize_inplace(PyObject *unicode, Py_ssize_t length) resize_inplace(PyObject *unicode, Py_ssize_t length)
{ {
wchar_t *wstr; wchar_t *wstr;
Py_ssize_t new_size;
assert(!PyUnicode_IS_COMPACT(unicode)); assert(!PyUnicode_IS_COMPACT(unicode));
assert(Py_REFCNT(unicode) == 1); assert(Py_REFCNT(unicode) == 1);
if (PyUnicode_IS_READY(unicode)) { if (PyUnicode_IS_READY(unicode)) {
Py_ssize_t char_size; Py_ssize_t char_size;
Py_ssize_t new_size;
int share_wstr, share_utf8; int share_wstr, share_utf8;
void *data; void *data;
data = _PyUnicode_DATA_ANY(unicode); data = _PyUnicode_DATA_ANY(unicode);
assert(data != NULL);
char_size = PyUnicode_KIND(unicode); char_size = PyUnicode_KIND(unicode);
share_wstr = _PyUnicode_SHARE_WSTR(unicode); share_wstr = _PyUnicode_SHARE_WSTR(unicode);
share_utf8 = _PyUnicode_SHARE_UTF8(unicode); share_utf8 = _PyUnicode_SHARE_UTF8(unicode);
if (!share_utf8 && _PyUnicode_HAS_UTF8_MEMORY(unicode))
{
PyObject_DEL(_PyUnicode_UTF8(unicode));
_PyUnicode_UTF8(unicode) = NULL;
_PyUnicode_UTF8_LENGTH(unicode) = 0;
}
if (length > (PY_SSIZE_T_MAX / char_size - 1)) { if (length > (PY_SSIZE_T_MAX / char_size - 1)) {
PyErr_NoMemory(); PyErr_NoMemory();
@ -715,6 +708,13 @@ resize_inplace(PyObject *unicode, Py_ssize_t length)
} }
new_size = (length + 1) * char_size; new_size = (length + 1) * char_size;
if (!share_utf8 && _PyUnicode_HAS_UTF8_MEMORY(unicode))
{
PyObject_DEL(_PyUnicode_UTF8(unicode));
_PyUnicode_UTF8(unicode) = NULL;
_PyUnicode_UTF8_LENGTH(unicode) = 0;
}
data = (PyObject *)PyObject_REALLOC(data, new_size); data = (PyObject *)PyObject_REALLOC(data, new_size);
if (data == NULL) { if (data == NULL) {
PyErr_NoMemory(); PyErr_NoMemory();
@ -743,8 +743,9 @@ resize_inplace(PyObject *unicode, Py_ssize_t length)
PyErr_NoMemory(); PyErr_NoMemory();
return -1; return -1;
} }
new_size = sizeof(wchar_t) * (length + 1);
wstr = _PyUnicode_WSTR(unicode); wstr = _PyUnicode_WSTR(unicode);
wstr = PyObject_REALLOC(wstr, sizeof(wchar_t) * (length + 1)); wstr = PyObject_REALLOC(wstr, new_size);
if (!wstr) { if (!wstr) {
PyErr_NoMemory(); PyErr_NoMemory();
return -1; return -1;
@ -760,9 +761,11 @@ static PyObject*
resize_copy(PyObject *unicode, Py_ssize_t length) resize_copy(PyObject *unicode, Py_ssize_t length)
{ {
Py_ssize_t copy_length; Py_ssize_t copy_length;
if (PyUnicode_IS_COMPACT(unicode)) { if (_PyUnicode_KIND(unicode) != PyUnicode_WCHAR_KIND) {
PyObject *copy; PyObject *copy;
assert(PyUnicode_IS_READY(unicode));
if (PyUnicode_READY(unicode) < 0)
return NULL;
copy = PyUnicode_New(length, PyUnicode_MAX_CHAR_VALUE(unicode)); copy = PyUnicode_New(length, PyUnicode_MAX_CHAR_VALUE(unicode));
if (copy == NULL) if (copy == NULL)
@ -774,8 +777,7 @@ resize_copy(PyObject *unicode, Py_ssize_t length)
} }
else { else {
PyObject *w; PyObject *w;
assert(_PyUnicode_WSTR(unicode) != NULL);
assert(_PyUnicode_DATA_ANY(unicode) == NULL);
w = (PyObject*)_PyUnicode_New(length); w = (PyObject*)_PyUnicode_New(length);
if (w == NULL) if (w == NULL)
return NULL; return NULL;