@@ -8842,15 +8842,13 @@ charmapencode_lookup(Py_UCS4 c, PyObject *mapping, unsigned char *replace)
8842
8842
}
8843
8843
8844
8844
static int
8845
- charmapencode_resize (PyObject * * outobj , Py_ssize_t * outpos , Py_ssize_t requiredsize )
8845
+ charmapencode_resize (PyBytesWriter * writer , Py_ssize_t * outpos , Py_ssize_t requiredsize )
8846
8846
{
8847
- Py_ssize_t outsize = PyBytes_GET_SIZE ( * outobj );
8847
+ Py_ssize_t outsize = PyBytesWriter_GetSize ( writer );
8848
8848
/* exponentially overallocate to minimize reallocations */
8849
- if (requiredsize < 2 * outsize )
8850
- requiredsize = 2 * outsize ;
8851
- if (_PyBytes_Resize (outobj , requiredsize ))
8852
- return -1 ;
8853
- return 0 ;
8849
+ if (requiredsize < 2 * outsize )
8850
+ requiredsize = 2 * outsize ;
8851
+ return PyBytesWriter_Resize (writer , requiredsize );
8854
8852
}
8855
8853
8856
8854
typedef enum charmapencode_result {
@@ -8864,22 +8862,22 @@ typedef enum charmapencode_result {
8864
8862
reallocation error occurred. The caller must decref the result */
8865
8863
static charmapencode_result
8866
8864
charmapencode_output (Py_UCS4 c , PyObject * mapping ,
8867
- PyObject * * outobj , Py_ssize_t * outpos )
8865
+ PyBytesWriter * writer , Py_ssize_t * outpos )
8868
8866
{
8869
8867
PyObject * rep ;
8870
8868
unsigned char replace ;
8871
8869
char * outstart ;
8872
- Py_ssize_t outsize = PyBytes_GET_SIZE ( * outobj );
8870
+ Py_ssize_t outsize = _PyBytesWriter_GetSize ( writer );
8873
8871
8874
8872
if (Py_IS_TYPE (mapping , & EncodingMapType )) {
8875
8873
int res = encoding_map_lookup (c , mapping );
8876
8874
Py_ssize_t requiredsize = * outpos + 1 ;
8877
8875
if (res == -1 )
8878
8876
return enc_FAILED ;
8879
8877
if (outsize < requiredsize )
8880
- if (charmapencode_resize (outobj , outpos , requiredsize ))
8878
+ if (charmapencode_resize (writer , outpos , requiredsize ))
8881
8879
return enc_EXCEPTION ;
8882
- outstart = PyBytes_AS_STRING ( * outobj );
8880
+ outstart = _PyBytesWriter_GetData ( writer );
8883
8881
outstart [(* outpos )++ ] = (char )res ;
8884
8882
return enc_SUCCESS ;
8885
8883
}
@@ -8894,23 +8892,23 @@ charmapencode_output(Py_UCS4 c, PyObject *mapping,
8894
8892
if (PyLong_Check (rep )) {
8895
8893
Py_ssize_t requiredsize = * outpos + 1 ;
8896
8894
if (outsize < requiredsize )
8897
- if (charmapencode_resize (outobj , outpos , requiredsize )) {
8895
+ if (charmapencode_resize (writer , outpos , requiredsize )) {
8898
8896
Py_DECREF (rep );
8899
8897
return enc_EXCEPTION ;
8900
8898
}
8901
- outstart = PyBytes_AS_STRING ( * outobj );
8899
+ outstart = _PyBytesWriter_GetData ( writer );
8902
8900
outstart [(* outpos )++ ] = (char )replace ;
8903
8901
}
8904
8902
else {
8905
8903
const char * repchars = PyBytes_AS_STRING (rep );
8906
8904
Py_ssize_t repsize = PyBytes_GET_SIZE (rep );
8907
8905
Py_ssize_t requiredsize = * outpos + repsize ;
8908
8906
if (outsize < requiredsize )
8909
- if (charmapencode_resize (outobj , outpos , requiredsize )) {
8907
+ if (charmapencode_resize (writer , outpos , requiredsize )) {
8910
8908
Py_DECREF (rep );
8911
8909
return enc_EXCEPTION ;
8912
8910
}
8913
- outstart = PyBytes_AS_STRING ( * outobj );
8911
+ outstart = _PyBytesWriter_GetData ( writer );
8914
8912
memcpy (outstart + * outpos , repchars , repsize );
8915
8913
* outpos += repsize ;
8916
8914
}
@@ -8926,7 +8924,7 @@ charmap_encoding_error(
8926
8924
PyObject * unicode , Py_ssize_t * inpos , PyObject * mapping ,
8927
8925
PyObject * * exceptionObject ,
8928
8926
_Py_error_handler * error_handler , PyObject * * error_handler_obj , const char * errors ,
8929
- PyObject * * res , Py_ssize_t * respos )
8927
+ PyBytesWriter * writer , Py_ssize_t * respos )
8930
8928
{
8931
8929
PyObject * repunicode = NULL ; /* initialize to prevent gcc warning */
8932
8930
Py_ssize_t size , repsize ;
@@ -8981,7 +8979,7 @@ charmap_encoding_error(
8981
8979
8982
8980
case _Py_ERROR_REPLACE :
8983
8981
for (collpos = collstartpos ; collpos < collendpos ; ++ collpos ) {
8984
- x = charmapencode_output ('?' , mapping , res , respos );
8982
+ x = charmapencode_output ('?' , mapping , writer , respos );
8985
8983
if (x == enc_EXCEPTION ) {
8986
8984
return -1 ;
8987
8985
}
@@ -9002,7 +9000,7 @@ charmap_encoding_error(
9002
9000
char * cp ;
9003
9001
sprintf (buffer , "&#%d;" , (int )PyUnicode_READ_CHAR (unicode , collpos ));
9004
9002
for (cp = buffer ; * cp ; ++ cp ) {
9005
- x = charmapencode_output (* cp , mapping , res , respos );
9003
+ x = charmapencode_output (* cp , mapping , writer , respos );
9006
9004
if (x == enc_EXCEPTION )
9007
9005
return -1 ;
9008
9006
else if (x == enc_FAILED ) {
@@ -9022,17 +9020,17 @@ charmap_encoding_error(
9022
9020
return -1 ;
9023
9021
if (PyBytes_Check (repunicode )) {
9024
9022
/* Directly copy bytes result to output. */
9025
- Py_ssize_t outsize = PyBytes_Size ( * res );
9023
+ Py_ssize_t outsize = PyBytesWriter_GetSize ( writer );
9026
9024
Py_ssize_t requiredsize ;
9027
9025
repsize = PyBytes_Size (repunicode );
9028
9026
requiredsize = * respos + repsize ;
9029
9027
if (requiredsize > outsize )
9030
9028
/* Make room for all additional bytes. */
9031
- if (charmapencode_resize (res , respos , requiredsize )) {
9029
+ if (charmapencode_resize (writer , respos , requiredsize )) {
9032
9030
Py_DECREF (repunicode );
9033
9031
return -1 ;
9034
9032
}
9035
- memcpy (PyBytes_AsString ( * res ) + * respos ,
9033
+ memcpy (( char * ) PyBytesWriter_GetData ( writer ) + * respos ,
9036
9034
PyBytes_AsString (repunicode ), repsize );
9037
9035
* respos += repsize ;
9038
9036
* inpos = newpos ;
@@ -9045,7 +9043,7 @@ charmap_encoding_error(
9045
9043
kind = PyUnicode_KIND (repunicode );
9046
9044
for (index = 0 ; index < repsize ; index ++ ) {
9047
9045
Py_UCS4 repch = PyUnicode_READ (kind , data , index );
9048
- x = charmapencode_output (repch , mapping , res , respos );
9046
+ x = charmapencode_output (repch , mapping , writer , respos );
9049
9047
if (x == enc_EXCEPTION ) {
9050
9048
Py_DECREF (repunicode );
9051
9049
return -1 ;
@@ -9067,65 +9065,64 @@ _PyUnicode_EncodeCharmap(PyObject *unicode,
9067
9065
PyObject * mapping ,
9068
9066
const char * errors )
9069
9067
{
9070
- /* output object */
9071
- PyObject * res = NULL ;
9072
- /* current input position */
9073
- Py_ssize_t inpos = 0 ;
9074
- Py_ssize_t size ;
9075
- /* current output position */
9076
- Py_ssize_t respos = 0 ;
9077
- PyObject * error_handler_obj = NULL ;
9078
- PyObject * exc = NULL ;
9079
- _Py_error_handler error_handler = _Py_ERROR_UNKNOWN ;
9080
- const void * data ;
9081
- int kind ;
9082
-
9083
- size = PyUnicode_GET_LENGTH (unicode );
9084
- data = PyUnicode_DATA (unicode );
9085
- kind = PyUnicode_KIND (unicode );
9086
-
9087
9068
/* Default to Latin-1 */
9088
- if (mapping == NULL )
9069
+ if (mapping == NULL ) {
9089
9070
return unicode_encode_ucs1 (unicode , errors , 256 );
9071
+ }
9072
+
9073
+ Py_ssize_t size = PyUnicode_GET_LENGTH (unicode );
9074
+ if (size == 0 ) {
9075
+ return Py_GetConstant (Py_CONSTANT_EMPTY_BYTES );
9076
+ }
9077
+ const void * data = PyUnicode_DATA (unicode );
9078
+ int kind = PyUnicode_KIND (unicode );
9090
9079
9080
+ PyObject * error_handler_obj = NULL ;
9081
+ PyObject * exc = NULL ;
9082
+
9083
+ /* output object */
9084
+ PyBytesWriter * writer ;
9091
9085
/* allocate enough for a simple encoding without
9092
9086
replacements, if we need more, we'll resize */
9093
- res = PyBytes_FromStringAndSize ( NULL , size );
9094
- if (res == NULL )
9087
+ writer = PyBytesWriter_Create ( size );
9088
+ if (writer == NULL ) {
9095
9089
goto onError ;
9096
- if (size == 0 )
9097
- return res ;
9090
+ }
9091
+
9092
+ /* current input position */
9093
+ Py_ssize_t inpos = 0 ;
9094
+ /* current output position */
9095
+ Py_ssize_t respos = 0 ;
9096
+ _Py_error_handler error_handler = _Py_ERROR_UNKNOWN ;
9098
9097
9099
9098
while (inpos < size ) {
9100
9099
Py_UCS4 ch = PyUnicode_READ (kind , data , inpos );
9101
9100
/* try to encode it */
9102
- charmapencode_result x = charmapencode_output (ch , mapping , & res , & respos );
9101
+ charmapencode_result x = charmapencode_output (ch , mapping , writer , & respos );
9103
9102
if (x == enc_EXCEPTION ) /* error */
9104
9103
goto onError ;
9105
9104
if (x == enc_FAILED ) { /* unencodable character */
9106
9105
if (charmap_encoding_error (unicode , & inpos , mapping ,
9107
9106
& exc ,
9108
9107
& error_handler , & error_handler_obj , errors ,
9109
- & res , & respos )) {
9108
+ writer , & respos )) {
9110
9109
goto onError ;
9111
9110
}
9112
9111
}
9113
- else
9112
+ else {
9114
9113
/* done with this character => adjust input position */
9115
9114
++ inpos ;
9115
+ }
9116
9116
}
9117
9117
9118
- /* Resize if we allocated to much */
9119
- if (respos < PyBytes_GET_SIZE (res ))
9120
- if (_PyBytes_Resize (& res , respos ) < 0 )
9121
- goto onError ;
9122
-
9123
9118
Py_XDECREF (exc );
9124
9119
Py_XDECREF (error_handler_obj );
9125
- return res ;
9120
+
9121
+ /* Resize if we allocated too much */
9122
+ return PyBytesWriter_FinishWithSize (writer , respos );
9126
9123
9127
9124
onError :
9128
- Py_XDECREF ( res );
9125
+ PyBytesWriter_Discard ( writer );
9129
9126
Py_XDECREF (exc );
9130
9127
Py_XDECREF (error_handler_obj );
9131
9128
return NULL ;
0 commit comments