Skip to content

Commit 8cfd7b4

Browse files
authored
gh-129813, PEP 782: Use PyBytesWriter in utf8_encoder() (#138874)
Replace the private _PyBytesWriter API with the new public PyBytesWriter API in utf8_encoder() and unicode_encode_ucs1().
1 parent 49e83e3 commit 8cfd7b4

File tree

2 files changed

+98
-77
lines changed

2 files changed

+98
-77
lines changed

Objects/stringlib/codecs.h

Lines changed: 35 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -257,16 +257,14 @@ STRINGLIB(utf8_decode)(const char **inptr, const char *end,
257257
/* UTF-8 encoder specialized for a Unicode kind to avoid the slow
258258
PyUnicode_READ() macro. Delete some parts of the code depending on the kind:
259259
UCS-1 strings don't need to handle surrogates for example. */
260-
Py_LOCAL_INLINE(char *)
261-
STRINGLIB(utf8_encoder)(_PyBytesWriter *writer,
262-
PyObject *unicode,
260+
Py_LOCAL_INLINE(PyBytesWriter*)
261+
STRINGLIB(utf8_encoder)(PyObject *unicode,
263262
const STRINGLIB_CHAR *data,
264263
Py_ssize_t size,
265264
_Py_error_handler error_handler,
266-
const char *errors)
265+
const char *errors,
266+
char **end)
267267
{
268-
Py_ssize_t i; /* index into data of next input character */
269-
char *p; /* next free byte in output buffer */
270268
#if STRINGLIB_SIZEOF_CHAR > 1
271269
PyObject *error_handler_obj = NULL;
272270
PyObject *exc = NULL;
@@ -284,14 +282,19 @@ STRINGLIB(utf8_encoder)(_PyBytesWriter *writer,
284282
if (size > PY_SSIZE_T_MAX / max_char_size) {
285283
/* integer overflow */
286284
PyErr_NoMemory();
285+
*end = NULL;
287286
return NULL;
288287
}
289288

290-
_PyBytesWriter_Init(writer);
291-
p = _PyBytesWriter_Alloc(writer, size * max_char_size);
292-
if (p == NULL)
289+
PyBytesWriter *writer = PyBytesWriter_Create(size * max_char_size);
290+
if (writer == NULL) {
291+
*end = NULL;
293292
return NULL;
293+
}
294+
/* next free byte in output buffer */
295+
char *p = PyBytesWriter_GetData(writer);
294296

297+
Py_ssize_t i; /* index into data of next input character */
295298
for (i = 0; i < size;) {
296299
Py_UCS4 ch = data[i++];
297300

@@ -348,7 +351,7 @@ STRINGLIB(utf8_encoder)(_PyBytesWriter *writer,
348351

349352
case _Py_ERROR_BACKSLASHREPLACE:
350353
/* subtract preallocated bytes */
351-
writer->min_size -= max_char_size * (endpos - startpos);
354+
writer->size -= max_char_size * (endpos - startpos);
352355
p = backslashreplace(writer, p,
353356
unicode, startpos, endpos);
354357
if (p == NULL)
@@ -358,7 +361,7 @@ STRINGLIB(utf8_encoder)(_PyBytesWriter *writer,
358361

359362
case _Py_ERROR_XMLCHARREFREPLACE:
360363
/* subtract preallocated bytes */
361-
writer->min_size -= max_char_size * (endpos - startpos);
364+
writer->size -= max_char_size * (endpos - startpos);
362365
p = xmlcharrefreplace(writer, p,
363366
unicode, startpos, endpos);
364367
if (p == NULL)
@@ -389,22 +392,25 @@ STRINGLIB(utf8_encoder)(_PyBytesWriter *writer,
389392

390393
if (newpos < startpos) {
391394
writer->overallocate = 1;
392-
p = _PyBytesWriter_Prepare(writer, p,
393-
max_char_size * (startpos - newpos));
394-
if (p == NULL)
395+
p = PyBytesWriter_GrowAndUpdatePointer(writer,
396+
max_char_size * (startpos - newpos),
397+
p);
398+
if (p == NULL) {
395399
goto error;
400+
}
396401
}
397402
else {
398403
/* subtract preallocated bytes */
399-
writer->min_size -= max_char_size * (newpos - startpos);
404+
writer->size -= max_char_size * (newpos - startpos);
400405
/* Only overallocate the buffer if it's not the last write */
401406
writer->overallocate = (newpos < size);
402407
}
403408

409+
char *rep_str;
410+
Py_ssize_t rep_len;
404411
if (PyBytes_Check(rep)) {
405-
p = _PyBytesWriter_WriteBytes(writer, p,
406-
PyBytes_AS_STRING(rep),
407-
PyBytes_GET_SIZE(rep));
412+
rep_str = PyBytes_AS_STRING(rep);
413+
rep_len = PyBytes_GET_SIZE(rep);
408414
}
409415
else {
410416
/* rep is unicode */
@@ -415,13 +421,16 @@ STRINGLIB(utf8_encoder)(_PyBytesWriter *writer,
415421
goto error;
416422
}
417423

418-
p = _PyBytesWriter_WriteBytes(writer, p,
419-
PyUnicode_DATA(rep),
420-
PyUnicode_GET_LENGTH(rep));
424+
rep_str = PyUnicode_DATA(rep);
425+
rep_len = PyUnicode_GET_LENGTH(rep);
421426
}
422427

423-
if (p == NULL)
428+
p = PyBytesWriter_GrowAndUpdatePointer(writer, rep_len, p);
429+
if (p == NULL) {
424430
goto error;
431+
}
432+
memcpy(p, rep_str, rep_len);
433+
p += rep_len;
425434
Py_CLEAR(rep);
426435

427436
i = newpos;
@@ -458,13 +467,16 @@ STRINGLIB(utf8_encoder)(_PyBytesWriter *writer,
458467
Py_XDECREF(error_handler_obj);
459468
Py_XDECREF(exc);
460469
#endif
461-
return p;
470+
*end = p;
471+
return writer;
462472

463473
#if STRINGLIB_SIZEOF_CHAR > 1
464474
error:
475+
PyBytesWriter_Discard(writer);
465476
Py_XDECREF(rep);
466477
Py_XDECREF(error_handler_obj);
467478
Py_XDECREF(exc);
479+
*end = NULL;
468480
return NULL;
469481
#endif
470482
}

0 commit comments

Comments
 (0)