Skip to content

Commit c5c3ba4

Browse files
committed
Add _PyBytesWriter_Resize() function
This function gives a control to the buffer size without using min_size.
1 parent 3c50ce3 commit c5c3ba4

File tree

2 files changed

+48
-19
lines changed

2 files changed

+48
-19
lines changed

Include/bytesobject.h

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -178,14 +178,31 @@ PyAPI_FUNC(void) _PyBytesWriter_Dealloc(_PyBytesWriter *writer);
178178
PyAPI_FUNC(void*) _PyBytesWriter_Alloc(_PyBytesWriter *writer,
179179
Py_ssize_t size);
180180

181-
/* Add *size* bytes to the buffer.
181+
/* Ensure that the buffer is large enough to write *size* bytes.
182+
Add size to the writer minimum size (min_size attribute).
183+
182184
str is the current pointer inside the buffer.
183185
Return the updated current pointer inside the buffer.
184186
Raise an exception and return NULL on error. */
185187
PyAPI_FUNC(void*) _PyBytesWriter_Prepare(_PyBytesWriter *writer,
186188
void *str,
187189
Py_ssize_t size);
188190

191+
/* Resize the buffer to make it larger.
192+
The new buffer may be larger than size bytes because of overallocation.
193+
Return the updated current pointer inside the buffer.
194+
Raise an exception and return NULL on error.
195+
196+
Note: size must be greater than the number of allocated bytes in the writer.
197+
198+
This function doesn't use the writer minimum size (min_size attribute).
199+
200+
See also _PyBytesWriter_Prepare().
201+
*/
202+
PyAPI_FUNC(void*) _PyBytesWriter_Resize(_PyBytesWriter *writer,
203+
void *str,
204+
Py_ssize_t size);
205+
189206
/* Write bytes.
190207
Raise an exception and return NULL on error. */
191208
PyAPI_FUNC(void*) _PyBytesWriter_WriteBytes(_PyBytesWriter *writer,

Objects/bytesobject.c

Lines changed: 30 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -3997,29 +3997,14 @@ _PyBytesWriter_CheckConsistency(_PyBytesWriter *writer, char *str)
39973997
}
39983998

39993999
void*
4000-
_PyBytesWriter_Prepare(_PyBytesWriter *writer, void *str, Py_ssize_t size)
4000+
_PyBytesWriter_Resize(_PyBytesWriter *writer, void *str, Py_ssize_t size)
40014001
{
40024002
Py_ssize_t allocated, pos;
40034003

40044004
_PyBytesWriter_CheckConsistency(writer, str);
4005-
assert(size >= 0);
4006-
4007-
if (size == 0) {
4008-
/* nothing to do */
4009-
return str;
4010-
}
4011-
4012-
if (writer->min_size > PY_SSIZE_T_MAX - size) {
4013-
PyErr_NoMemory();
4014-
goto error;
4015-
}
4016-
writer->min_size += size;
4017-
4018-
allocated = writer->allocated;
4019-
if (writer->min_size <= allocated)
4020-
return str;
4005+
assert(writer->allocated < size);
40214006

4022-
allocated = writer->min_size;
4007+
allocated = size;
40234008
if (writer->overallocate
40244009
&& allocated <= (PY_SSIZE_T_MAX - allocated / OVERALLOCATE_FACTOR)) {
40254010
/* overallocate to limit the number of realloc() */
@@ -4080,6 +4065,33 @@ _PyBytesWriter_Prepare(_PyBytesWriter *writer, void *str, Py_ssize_t size)
40804065
return NULL;
40814066
}
40824067

4068+
void*
4069+
_PyBytesWriter_Prepare(_PyBytesWriter *writer, void *str, Py_ssize_t size)
4070+
{
4071+
Py_ssize_t new_min_size;
4072+
4073+
_PyBytesWriter_CheckConsistency(writer, str);
4074+
assert(size >= 0);
4075+
4076+
if (size == 0) {
4077+
/* nothing to do */
4078+
return str;
4079+
}
4080+
4081+
if (writer->min_size > PY_SSIZE_T_MAX - size) {
4082+
PyErr_NoMemory();
4083+
_PyBytesWriter_Dealloc(writer);
4084+
return NULL;
4085+
}
4086+
new_min_size = writer->min_size + size;
4087+
4088+
if (new_min_size > writer->allocated)
4089+
str = _PyBytesWriter_Resize(writer, str, new_min_size);
4090+
4091+
writer->min_size = new_min_size;
4092+
return str;
4093+
}
4094+
40834095
/* Allocate the buffer to write size bytes.
40844096
Return the pointer to the beginning of buffer data.
40854097
Raise an exception and return NULL on error. */

0 commit comments

Comments
 (0)