Writer APIs: use empty string singletons

Modify _PyBytesWriter_Finish() and _PyUnicodeWriter_Finish() to return the
empty bytes/Unicode string if the string is empty.
This commit is contained in:
Victor Stinner 2015-10-12 13:29:43 +02:00
parent c29e29bed1
commit 6c2cdae9e6
2 changed files with 33 additions and 19 deletions

View File

@ -4019,19 +4019,24 @@ _PyBytesWriter_Finish(_PyBytesWriter *writer, void *str)
_PyBytesWriter_CheckConsistency(writer, str); _PyBytesWriter_CheckConsistency(writer, str);
pos = _PyBytesWriter_GetPos(writer, str); pos = _PyBytesWriter_GetPos(writer, str);
if (!writer->use_small_buffer) { if (pos == 0) {
Py_CLEAR(writer->buffer);
/* Get the empty byte string singleton */
result = PyBytes_FromStringAndSize(NULL, 0);
}
else if (writer->use_small_buffer) {
result = PyBytes_FromStringAndSize(writer->small_buffer, pos);
}
else {
result = writer->buffer;
writer->buffer = NULL;
if (pos != writer->allocated) { if (pos != writer->allocated) {
if (_PyBytes_Resize(&writer->buffer, pos)) { if (_PyBytes_Resize(&result, pos)) {
assert(writer->buffer == NULL); assert(result == NULL);
return NULL; return NULL;
} }
} }
result = writer->buffer;
writer->buffer = NULL;
}
else {
result = PyBytes_FromStringAndSize(writer->small_buffer, pos);
} }
return result; return result;
} }

View File

@ -13715,17 +13715,26 @@ _PyUnicodeWriter_Finish(_PyUnicodeWriter *writer)
assert(PyUnicode_GET_LENGTH(str) == writer->pos); assert(PyUnicode_GET_LENGTH(str) == writer->pos);
return str; return str;
} }
if (PyUnicode_GET_LENGTH(writer->buffer) != writer->pos) { if (writer->pos == 0) {
PyObject *newbuffer; Py_CLEAR(writer->buffer);
newbuffer = resize_compact(writer->buffer, writer->pos);
if (newbuffer == NULL) { /* Get the empty Unicode string singleton ('') */
Py_CLEAR(writer->buffer); _Py_INCREF_UNICODE_EMPTY();
return NULL; str = unicode_empty;
}
writer->buffer = newbuffer;
} }
str = writer->buffer; else {
writer->buffer = NULL; str = writer->buffer;
writer->buffer = NULL;
if (PyUnicode_GET_LENGTH(str) != writer->pos) {
PyObject *str2;
str2 = resize_compact(str, writer->pos);
if (str2 == NULL)
return NULL;
str = str2;
}
}
assert(_PyUnicode_CheckConsistency(str, 1)); assert(_PyUnicode_CheckConsistency(str, 1));
return unicode_result_ready(str); return unicode_result_ready(str);
} }