Add _PyBytesWriter_Resize() function

This function gives a control to the buffer size without using min_size.
This commit is contained in:
Victor Stinner 2015-10-14 13:56:47 +02:00
parent 3c50ce39bf
commit c5c3ba4bec
2 changed files with 48 additions and 19 deletions

View File

@ -178,7 +178,9 @@ PyAPI_FUNC(void) _PyBytesWriter_Dealloc(_PyBytesWriter *writer);
PyAPI_FUNC(void*) _PyBytesWriter_Alloc(_PyBytesWriter *writer,
Py_ssize_t size);
/* Add *size* bytes to the buffer.
/* Ensure that the buffer is large enough to write *size* bytes.
Add size to the writer minimum size (min_size attribute).
str is the current pointer inside the buffer.
Return the updated current pointer inside the buffer.
Raise an exception and return NULL on error. */
@ -186,6 +188,21 @@ PyAPI_FUNC(void*) _PyBytesWriter_Prepare(_PyBytesWriter *writer,
void *str,
Py_ssize_t size);
/* Resize the buffer to make it larger.
The new buffer may be larger than size bytes because of overallocation.
Return the updated current pointer inside the buffer.
Raise an exception and return NULL on error.
Note: size must be greater than the number of allocated bytes in the writer.
This function doesn't use the writer minimum size (min_size attribute).
See also _PyBytesWriter_Prepare().
*/
PyAPI_FUNC(void*) _PyBytesWriter_Resize(_PyBytesWriter *writer,
void *str,
Py_ssize_t size);
/* Write bytes.
Raise an exception and return NULL on error. */
PyAPI_FUNC(void*) _PyBytesWriter_WriteBytes(_PyBytesWriter *writer,

View File

@ -3997,29 +3997,14 @@ _PyBytesWriter_CheckConsistency(_PyBytesWriter *writer, char *str)
}
void*
_PyBytesWriter_Prepare(_PyBytesWriter *writer, void *str, Py_ssize_t size)
_PyBytesWriter_Resize(_PyBytesWriter *writer, void *str, Py_ssize_t size)
{
Py_ssize_t allocated, pos;
_PyBytesWriter_CheckConsistency(writer, str);
assert(size >= 0);
assert(writer->allocated < size);
if (size == 0) {
/* nothing to do */
return str;
}
if (writer->min_size > PY_SSIZE_T_MAX - size) {
PyErr_NoMemory();
goto error;
}
writer->min_size += size;
allocated = writer->allocated;
if (writer->min_size <= allocated)
return str;
allocated = writer->min_size;
allocated = size;
if (writer->overallocate
&& allocated <= (PY_SSIZE_T_MAX - allocated / OVERALLOCATE_FACTOR)) {
/* overallocate to limit the number of realloc() */
@ -4080,6 +4065,33 @@ error:
return NULL;
}
void*
_PyBytesWriter_Prepare(_PyBytesWriter *writer, void *str, Py_ssize_t size)
{
Py_ssize_t new_min_size;
_PyBytesWriter_CheckConsistency(writer, str);
assert(size >= 0);
if (size == 0) {
/* nothing to do */
return str;
}
if (writer->min_size > PY_SSIZE_T_MAX - size) {
PyErr_NoMemory();
_PyBytesWriter_Dealloc(writer);
return NULL;
}
new_min_size = writer->min_size + size;
if (new_min_size > writer->allocated)
str = _PyBytesWriter_Resize(writer, str, new_min_size);
writer->min_size = new_min_size;
return str;
}
/* Allocate the buffer to write size bytes.
Return the pointer to the beginning of buffer data.
Raise an exception and return NULL on error. */