Change PyUnicode_EncodeCharmap() to return bytes objects
(which simplifies the implementation a little, because bytes objects are resizable in place).
This commit is contained in:
parent
aef90f4dd4
commit
827b055ffe
@ -3541,34 +3541,35 @@ static PyObject *charmapencode_lookup(Py_UNICODE c, PyObject *mapping)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
charmapencode_resize(PyObject **outobj, Py_ssize_t *outpos, Py_ssize_t requiredsize)
|
charmapencode_resize(PyObject *outobj, Py_ssize_t *outpos, Py_ssize_t requiredsize)
|
||||||
{
|
{
|
||||||
Py_ssize_t outsize = PyString_GET_SIZE(*outobj);
|
Py_ssize_t outsize = PyBytes_GET_SIZE( outobj);
|
||||||
/* exponentially overallocate to minimize reallocations */
|
/* exponentially overallocate to minimize reallocations */
|
||||||
if (requiredsize < 2*outsize)
|
if (requiredsize < 2*outsize)
|
||||||
requiredsize = 2*outsize;
|
requiredsize = 2*outsize;
|
||||||
if (_PyString_Resize(outobj, requiredsize)) {
|
if (PyBytes_Resize(outobj, requiredsize)) {
|
||||||
return 0;
|
Py_DECREF(outobj);
|
||||||
|
return -1;
|
||||||
}
|
}
|
||||||
return 1;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
typedef enum charmapencode_result {
|
typedef enum charmapencode_result {
|
||||||
enc_SUCCESS, enc_FAILED, enc_EXCEPTION
|
enc_SUCCESS, enc_FAILED, enc_EXCEPTION
|
||||||
}charmapencode_result;
|
}charmapencode_result;
|
||||||
/* lookup the character, put the result in the output string and adjust
|
/* lookup the character, put the result in the output string and adjust
|
||||||
various state variables. Reallocate the output string if not enough
|
various state variables. Resize the output bytes object if not enough
|
||||||
space is available. Return a new reference to the object that
|
space is available. Return a new reference to the object that
|
||||||
was put in the output buffer, or Py_None, if the mapping was undefined
|
was put in the output buffer, or Py_None, if the mapping was undefined
|
||||||
(in which case no character was written) or NULL, if a
|
(in which case no character was written) or NULL, if a
|
||||||
reallocation error occurred. The caller must decref the result */
|
reallocation error occurred. The caller must decref the result */
|
||||||
static
|
static
|
||||||
charmapencode_result charmapencode_output(Py_UNICODE c, PyObject *mapping,
|
charmapencode_result charmapencode_output(Py_UNICODE c, PyObject *mapping,
|
||||||
PyObject **outobj, Py_ssize_t *outpos)
|
PyObject *outobj, Py_ssize_t *outpos)
|
||||||
{
|
{
|
||||||
PyObject *rep;
|
PyObject *rep;
|
||||||
char *outstart;
|
char *outstart;
|
||||||
Py_ssize_t outsize = PyString_GET_SIZE(*outobj);
|
Py_ssize_t outsize = PyBytes_GET_SIZE(outobj);
|
||||||
|
|
||||||
if (mapping->ob_type == &EncodingMapType) {
|
if (mapping->ob_type == &EncodingMapType) {
|
||||||
int res = encoding_map_lookup(c, mapping);
|
int res = encoding_map_lookup(c, mapping);
|
||||||
@ -3576,9 +3577,9 @@ charmapencode_result charmapencode_output(Py_UNICODE c, PyObject *mapping,
|
|||||||
if (res == -1)
|
if (res == -1)
|
||||||
return enc_FAILED;
|
return enc_FAILED;
|
||||||
if (outsize<requiredsize)
|
if (outsize<requiredsize)
|
||||||
if (!charmapencode_resize(outobj, outpos, requiredsize))
|
if (charmapencode_resize(outobj, outpos, requiredsize))
|
||||||
return enc_EXCEPTION;
|
return enc_EXCEPTION;
|
||||||
outstart = PyString_AS_STRING(*outobj);
|
outstart = PyBytes_AS_STRING(outobj);
|
||||||
outstart[(*outpos)++] = (char)res;
|
outstart[(*outpos)++] = (char)res;
|
||||||
return enc_SUCCESS;
|
return enc_SUCCESS;
|
||||||
}
|
}
|
||||||
@ -3593,11 +3594,11 @@ charmapencode_result charmapencode_output(Py_UNICODE c, PyObject *mapping,
|
|||||||
if (PyInt_Check(rep)) {
|
if (PyInt_Check(rep)) {
|
||||||
Py_ssize_t requiredsize = *outpos+1;
|
Py_ssize_t requiredsize = *outpos+1;
|
||||||
if (outsize<requiredsize)
|
if (outsize<requiredsize)
|
||||||
if (!charmapencode_resize(outobj, outpos, requiredsize)) {
|
if (charmapencode_resize(outobj, outpos, requiredsize)) {
|
||||||
Py_DECREF(rep);
|
Py_DECREF(rep);
|
||||||
return enc_EXCEPTION;
|
return enc_EXCEPTION;
|
||||||
}
|
}
|
||||||
outstart = PyString_AS_STRING(*outobj);
|
outstart = PyBytes_AS_STRING(outobj);
|
||||||
outstart[(*outpos)++] = (char)PyInt_AS_LONG(rep);
|
outstart[(*outpos)++] = (char)PyInt_AS_LONG(rep);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
@ -3605,11 +3606,11 @@ charmapencode_result charmapencode_output(Py_UNICODE c, PyObject *mapping,
|
|||||||
Py_ssize_t repsize = PyString_GET_SIZE(rep);
|
Py_ssize_t repsize = PyString_GET_SIZE(rep);
|
||||||
Py_ssize_t requiredsize = *outpos+repsize;
|
Py_ssize_t requiredsize = *outpos+repsize;
|
||||||
if (outsize<requiredsize)
|
if (outsize<requiredsize)
|
||||||
if (!charmapencode_resize(outobj, outpos, requiredsize)) {
|
if (charmapencode_resize(outobj, outpos, requiredsize)) {
|
||||||
Py_DECREF(rep);
|
Py_DECREF(rep);
|
||||||
return enc_EXCEPTION;
|
return enc_EXCEPTION;
|
||||||
}
|
}
|
||||||
outstart = PyString_AS_STRING(*outobj);
|
outstart = PyBytes_AS_STRING(outobj);
|
||||||
memcpy(outstart + *outpos, repchars, repsize);
|
memcpy(outstart + *outpos, repchars, repsize);
|
||||||
*outpos += repsize;
|
*outpos += repsize;
|
||||||
}
|
}
|
||||||
@ -3625,7 +3626,7 @@ int charmap_encoding_error(
|
|||||||
const Py_UNICODE *p, Py_ssize_t size, Py_ssize_t *inpos, PyObject *mapping,
|
const Py_UNICODE *p, Py_ssize_t size, Py_ssize_t *inpos, PyObject *mapping,
|
||||||
PyObject **exceptionObject,
|
PyObject **exceptionObject,
|
||||||
int *known_errorHandler, PyObject **errorHandler, const char *errors,
|
int *known_errorHandler, PyObject **errorHandler, const char *errors,
|
||||||
PyObject **res, Py_ssize_t *respos)
|
PyObject *res, Py_ssize_t *respos)
|
||||||
{
|
{
|
||||||
PyObject *repunicode = NULL; /* initialize to prevent gcc warning */
|
PyObject *repunicode = NULL; /* initialize to prevent gcc warning */
|
||||||
Py_ssize_t repsize;
|
Py_ssize_t repsize;
|
||||||
@ -3760,7 +3761,7 @@ PyObject *PyUnicode_EncodeCharmap(const Py_UNICODE *p,
|
|||||||
|
|
||||||
/* allocate enough for a simple encoding without
|
/* allocate enough for a simple encoding without
|
||||||
replacements, if we need more, we'll resize */
|
replacements, if we need more, we'll resize */
|
||||||
res = PyString_FromStringAndSize(NULL, size);
|
res = PyBytes_FromStringAndSize(NULL, size);
|
||||||
if (res == NULL)
|
if (res == NULL)
|
||||||
goto onError;
|
goto onError;
|
||||||
if (size == 0)
|
if (size == 0)
|
||||||
@ -3768,14 +3769,14 @@ PyObject *PyUnicode_EncodeCharmap(const Py_UNICODE *p,
|
|||||||
|
|
||||||
while (inpos<size) {
|
while (inpos<size) {
|
||||||
/* try to encode it */
|
/* try to encode it */
|
||||||
charmapencode_result x = charmapencode_output(p[inpos], mapping, &res, &respos);
|
charmapencode_result x = charmapencode_output(p[inpos], mapping, res, &respos);
|
||||||
if (x==enc_EXCEPTION) /* error */
|
if (x==enc_EXCEPTION) /* error */
|
||||||
goto onError;
|
goto onError;
|
||||||
if (x==enc_FAILED) { /* unencodable character */
|
if (x==enc_FAILED) { /* unencodable character */
|
||||||
if (charmap_encoding_error(p, size, &inpos, mapping,
|
if (charmap_encoding_error(p, size, &inpos, mapping,
|
||||||
&exc,
|
&exc,
|
||||||
&known_errorHandler, &errorHandler, errors,
|
&known_errorHandler, &errorHandler, errors,
|
||||||
&res, &respos)) {
|
res, &respos)) {
|
||||||
goto onError;
|
goto onError;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -3785,8 +3786,8 @@ PyObject *PyUnicode_EncodeCharmap(const Py_UNICODE *p,
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Resize if we allocated to much */
|
/* Resize if we allocated to much */
|
||||||
if (respos<PyString_GET_SIZE(res)) {
|
if (respos<PyBytes_GET_SIZE(res)) {
|
||||||
if (_PyString_Resize(&res, respos))
|
if (PyBytes_Resize(res, respos))
|
||||||
goto onError;
|
goto onError;
|
||||||
}
|
}
|
||||||
Py_XDECREF(exc);
|
Py_XDECREF(exc);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user