Skip to content

Commit c7b11b7

Browse files
authored
gh-139156: Use PyBytesWriter in PyUnicode_EncodeCodePage() (#139259)
Replace PyBytes_FromStringAndSize() and _PyBytes_Resize() with the PyBytesWriter API.
1 parent c9a79a0 commit c7b11b7

File tree

1 file changed

+36
-51
lines changed

1 file changed

+36
-51
lines changed

Objects/unicodeobject.c

Lines changed: 36 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -7988,7 +7988,7 @@ encode_code_page_flags(UINT code_page, const char *errors)
79887988
* an OSError and returns -1 on other error.
79897989
*/
79907990
static int
7991-
encode_code_page_strict(UINT code_page, PyObject **outbytes,
7991+
encode_code_page_strict(UINT code_page, PyBytesWriter **writer,
79927992
PyObject *unicode, Py_ssize_t offset, int len,
79937993
const char* errors)
79947994
{
@@ -8034,25 +8034,21 @@ encode_code_page_strict(UINT code_page, PyObject **outbytes,
80348034
goto done;
80358035
}
80368036

8037-
if (*outbytes == NULL) {
8037+
if (*writer == NULL) {
80388038
/* Create string object */
8039-
*outbytes = PyBytes_FromStringAndSize(NULL, outsize);
8040-
if (*outbytes == NULL) {
8039+
*writer = PyBytesWriter_Create(outsize);
8040+
if (*writer == NULL) {
80418041
goto done;
80428042
}
8043-
out = PyBytes_AS_STRING(*outbytes);
8043+
out = PyBytesWriter_GetData(*writer);
80448044
}
80458045
else {
80468046
/* Extend string object */
8047-
const Py_ssize_t n = PyBytes_Size(*outbytes);
8048-
if (outsize > PY_SSIZE_T_MAX - n) {
8049-
PyErr_NoMemory();
8050-
goto done;
8051-
}
8052-
if (_PyBytes_Resize(outbytes, n + outsize) < 0) {
8047+
Py_ssize_t n = PyBytesWriter_GetSize(*writer);
8048+
if (PyBytesWriter_Grow(*writer, outsize) < 0) {
80538049
goto done;
80548050
}
8055-
out = PyBytes_AS_STRING(*outbytes) + n;
8051+
out = (char*)PyBytesWriter_GetData(*writer) + n;
80568052
}
80578053

80588054
/* Do the conversion */
@@ -8089,7 +8085,7 @@ encode_code_page_strict(UINT code_page, PyObject **outbytes,
80898085
* -1 on other error.
80908086
*/
80918087
static int
8092-
encode_code_page_errors(UINT code_page, PyObject **outbytes,
8088+
encode_code_page_errors(UINT code_page, PyBytesWriter **writer,
80938089
PyObject *unicode, Py_ssize_t unicode_offset,
80948090
Py_ssize_t insize, const char* errors)
80958091
{
@@ -8108,7 +8104,7 @@ encode_code_page_errors(UINT code_page, PyObject **outbytes,
81088104
PyObject *exc = NULL;
81098105
PyObject *encoding_obj = NULL;
81108106
const char *encoding;
8111-
Py_ssize_t newpos, newoutsize;
8107+
Py_ssize_t newpos;
81128108
PyObject *rep;
81138109
int ret = -1;
81148110

@@ -8141,23 +8137,21 @@ encode_code_page_errors(UINT code_page, PyObject **outbytes,
81418137
}
81428138
outsize = insize * Py_ARRAY_LENGTH(buffer);
81438139

8144-
if (*outbytes == NULL) {
8140+
if (*writer == NULL) {
81458141
/* Create string object */
8146-
*outbytes = PyBytes_FromStringAndSize(NULL, outsize);
8147-
if (*outbytes == NULL)
8142+
*writer = PyBytesWriter_Create(outsize);
8143+
if (*writer == NULL) {
81488144
goto error;
8149-
out = PyBytes_AS_STRING(*outbytes);
8145+
}
8146+
out = PyBytesWriter_GetData(*writer);
81508147
}
81518148
else {
81528149
/* Extend string object */
8153-
Py_ssize_t n = PyBytes_Size(*outbytes);
8154-
if (n > PY_SSIZE_T_MAX - outsize) {
8155-
PyErr_NoMemory();
8150+
Py_ssize_t n = PyBytesWriter_GetSize(*writer);
8151+
if (PyBytesWriter_Grow(*writer, outsize) < 0) {
81568152
goto error;
81578153
}
8158-
if (_PyBytes_Resize(outbytes, n + outsize) < 0)
8159-
goto error;
8160-
out = PyBytes_AS_STRING(*outbytes) + n;
8154+
out = (char*)PyBytesWriter_GetData(*writer) + n;
81618155
}
81628156

81638157
/* Encode the string character per character */
@@ -8206,13 +8200,11 @@ encode_code_page_errors(UINT code_page, PyObject **outbytes,
82068200
outsize = PyBytes_GET_SIZE(rep);
82078201
morebytes += outsize;
82088202
if (morebytes > 0) {
8209-
Py_ssize_t offset = out - PyBytes_AS_STRING(*outbytes);
8210-
newoutsize = PyBytes_GET_SIZE(*outbytes) + morebytes;
8211-
if (_PyBytes_Resize(outbytes, newoutsize) < 0) {
8203+
out = PyBytesWriter_GrowAndUpdatePointer(*writer, morebytes, out);
8204+
if (out == NULL) {
82128205
Py_DECREF(rep);
82138206
goto error;
82148207
}
8215-
out = PyBytes_AS_STRING(*outbytes) + offset;
82168208
}
82178209
memcpy(out, PyBytes_AS_STRING(rep), outsize);
82188210
out += outsize;
@@ -8225,13 +8217,11 @@ encode_code_page_errors(UINT code_page, PyObject **outbytes,
82258217
outsize = PyUnicode_GET_LENGTH(rep);
82268218
morebytes += outsize;
82278219
if (morebytes > 0) {
8228-
Py_ssize_t offset = out - PyBytes_AS_STRING(*outbytes);
8229-
newoutsize = PyBytes_GET_SIZE(*outbytes) + morebytes;
8230-
if (_PyBytes_Resize(outbytes, newoutsize) < 0) {
8220+
out = PyBytesWriter_GrowAndUpdatePointer(*writer, morebytes, out);
8221+
if (out == NULL) {
82318222
Py_DECREF(rep);
82328223
goto error;
82338224
}
8234-
out = PyBytes_AS_STRING(*outbytes) + offset;
82358225
}
82368226
kind = PyUnicode_KIND(rep);
82378227
data = PyUnicode_DATA(rep);
@@ -8254,10 +8244,11 @@ encode_code_page_errors(UINT code_page, PyObject **outbytes,
82548244
}
82558245
/* write a NUL byte */
82568246
*out = 0;
8257-
outsize = out - PyBytes_AS_STRING(*outbytes);
8258-
assert(outsize <= PyBytes_GET_SIZE(*outbytes));
8259-
if (_PyBytes_Resize(outbytes, outsize) < 0)
8247+
outsize = out - (char*)PyBytesWriter_GetData(*writer);
8248+
assert(outsize <= PyBytesWriter_GetSize(*writer));
8249+
if (PyBytesWriter_Resize(*writer, outsize) < 0) {
82608250
goto error;
8251+
}
82618252
ret = 0;
82628253

82638254
error:
@@ -8267,13 +8258,14 @@ encode_code_page_errors(UINT code_page, PyObject **outbytes,
82678258
return ret;
82688259
}
82698260

8270-
static PyObject *
8271-
encode_code_page(int code_page,
8272-
PyObject *unicode,
8273-
const char *errors)
8261+
8262+
PyObject *
8263+
PyUnicode_EncodeCodePage(int code_page,
8264+
PyObject *unicode,
8265+
const char *errors)
82748266
{
82758267
Py_ssize_t len;
8276-
PyObject *outbytes = NULL;
8268+
PyBytesWriter *writer = NULL;
82778269
Py_ssize_t offset;
82788270
int chunk_len, ret, done;
82798271

@@ -8307,32 +8299,25 @@ encode_code_page(int code_page,
83078299
done = 1;
83088300
}
83098301

8310-
ret = encode_code_page_strict(code_page, &outbytes,
8302+
ret = encode_code_page_strict(code_page, &writer,
83118303
unicode, offset, chunk_len,
83128304
errors);
83138305
if (ret == -2)
8314-
ret = encode_code_page_errors(code_page, &outbytes,
8306+
ret = encode_code_page_errors(code_page, &writer,
83158307
unicode, offset,
83168308
chunk_len, errors);
83178309
if (ret < 0) {
8318-
Py_XDECREF(outbytes);
8310+
PyBytesWriter_Discard(writer);
83198311
return NULL;
83208312
}
83218313

83228314
offset += chunk_len;
83238315
len -= chunk_len;
83248316
} while (!done);
83258317

8326-
return outbytes;
8318+
return PyBytesWriter_Finish(writer);
83278319
}
83288320

8329-
PyObject *
8330-
PyUnicode_EncodeCodePage(int code_page,
8331-
PyObject *unicode,
8332-
const char *errors)
8333-
{
8334-
return encode_code_page(code_page, unicode, errors);
8335-
}
83368321

83378322
PyObject *
83388323
PyUnicode_AsMBCSString(PyObject *unicode)

0 commit comments

Comments
 (0)