@@ -8858,15 +8858,13 @@ charmapencode_lookup(Py_UCS4 c, PyObject *mapping, unsigned char *replace)
88588858}
88598859
88608860static  int 
8861- charmapencode_resize (PyObject   * * outobj , Py_ssize_t  * outpos , Py_ssize_t  requiredsize )
8861+ charmapencode_resize (PyBytesWriter   * writer , Py_ssize_t  * outpos , Py_ssize_t  requiredsize )
88628862{
8863-     Py_ssize_t  outsize  =  PyBytes_GET_SIZE ( * outobj );
8863+     Py_ssize_t  outsize  =  PyBytesWriter_GetSize ( writer );
88648864    /* exponentially overallocate to minimize reallocations */ 
8865-     if  (requiredsize  <  2 * outsize )
8866-         requiredsize  =  2 * outsize ;
8867-     if  (_PyBytes_Resize (outobj , requiredsize ))
8868-         return  -1 ;
8869-     return  0 ;
8865+     if  (requiredsize  <  2  *  outsize )
8866+         requiredsize  =  2  *  outsize ;
8867+     return  PyBytesWriter_Resize (writer , requiredsize );
88708868}
88718869
88728870typedef  enum  charmapencode_result  {
@@ -8880,22 +8878,22 @@ typedef enum charmapencode_result {
88808878   reallocation error occurred. The caller must decref the result */ 
88818879static  charmapencode_result 
88828880charmapencode_output (Py_UCS4  c , PyObject  * mapping ,
8883-                      PyObject   * * outobj , Py_ssize_t  * outpos )
8881+                      PyBytesWriter   * writer , Py_ssize_t  * outpos )
88848882{
88858883    PyObject  * rep ;
88868884    unsigned char   replace ;
88878885    char  * outstart ;
8888-     Py_ssize_t  outsize  =  PyBytes_GET_SIZE ( * outobj );
8886+     Py_ssize_t  outsize  =  PyBytesWriter_GetSize ( writer );
88898887
88908888    if  (Py_IS_TYPE (mapping , & EncodingMapType )) {
88918889        int  res  =  encoding_map_lookup (c , mapping );
88928890        Py_ssize_t  requiredsize  =  * outpos + 1 ;
88938891        if  (res  ==  -1 )
88948892            return  enc_FAILED ;
88958893        if  (outsize < requiredsize )
8896-             if  (charmapencode_resize (outobj , outpos , requiredsize ))
8894+             if  (charmapencode_resize (writer , outpos , requiredsize ))
88978895                return  enc_EXCEPTION ;
8898-         outstart  =  PyBytes_AS_STRING ( * outobj );
8896+         outstart  =  PyBytesWriter_GetData ( writer );
88998897        outstart [(* outpos )++ ] =  (char )res ;
89008898        return  enc_SUCCESS ;
89018899    }
@@ -8910,23 +8908,23 @@ charmapencode_output(Py_UCS4 c, PyObject *mapping,
89108908        if  (PyLong_Check (rep )) {
89118909            Py_ssize_t  requiredsize  =  * outpos + 1 ;
89128910            if  (outsize < requiredsize )
8913-                 if  (charmapencode_resize (outobj , outpos , requiredsize )) {
8911+                 if  (charmapencode_resize (writer , outpos , requiredsize )) {
89148912                    Py_DECREF (rep );
89158913                    return  enc_EXCEPTION ;
89168914                }
8917-             outstart  =  PyBytes_AS_STRING ( * outobj );
8915+             outstart  =  PyBytesWriter_GetData ( writer );
89188916            outstart [(* outpos )++ ] =  (char )replace ;
89198917        }
89208918        else  {
89218919            const  char  * repchars  =  PyBytes_AS_STRING (rep );
89228920            Py_ssize_t  repsize  =  PyBytes_GET_SIZE (rep );
89238921            Py_ssize_t  requiredsize  =  * outpos + repsize ;
89248922            if  (outsize < requiredsize )
8925-                 if  (charmapencode_resize (outobj , outpos , requiredsize )) {
8923+                 if  (charmapencode_resize (writer , outpos , requiredsize )) {
89268924                    Py_DECREF (rep );
89278925                    return  enc_EXCEPTION ;
89288926                }
8929-             outstart  =  PyBytes_AS_STRING ( * outobj );
8927+             outstart  =  PyBytesWriter_GetData ( writer );
89308928            memcpy (outstart  +  * outpos , repchars , repsize );
89318929            * outpos  +=  repsize ;
89328930        }
@@ -8942,7 +8940,7 @@ charmap_encoding_error(
89428940    PyObject  * unicode , Py_ssize_t  * inpos , PyObject  * mapping ,
89438941    PyObject  * * exceptionObject ,
89448942    _Py_error_handler  * error_handler , PyObject  * * error_handler_obj , const  char  * errors ,
8945-     PyObject   * * res , Py_ssize_t  * respos )
8943+     PyBytesWriter   * writer , Py_ssize_t  * respos )
89468944{
89478945    PyObject  * repunicode  =  NULL ; /* initialize to prevent gcc warning */ 
89488946    Py_ssize_t  size , repsize ;
@@ -8997,7 +8995,7 @@ charmap_encoding_error(
89978995
89988996    case  _Py_ERROR_REPLACE :
89998997        for  (collpos  =  collstartpos ; collpos < collendpos ; ++ collpos ) {
9000-             x  =  charmapencode_output ('?' , mapping , res , respos );
8998+             x  =  charmapencode_output ('?' , mapping , writer , respos );
90018999            if  (x == enc_EXCEPTION ) {
90029000                return  -1 ;
90039001            }
@@ -9018,7 +9016,7 @@ charmap_encoding_error(
90189016            char  * cp ;
90199017            sprintf (buffer , "&#%d;" , (int )PyUnicode_READ_CHAR (unicode , collpos ));
90209018            for  (cp  =  buffer ; * cp ; ++ cp ) {
9021-                 x  =  charmapencode_output (* cp , mapping , res , respos );
9019+                 x  =  charmapencode_output (* cp , mapping , writer , respos );
90229020                if  (x == enc_EXCEPTION )
90239021                    return  -1 ;
90249022                else  if  (x == enc_FAILED ) {
@@ -9038,17 +9036,17 @@ charmap_encoding_error(
90389036            return  -1 ;
90399037        if  (PyBytes_Check (repunicode )) {
90409038            /* Directly copy bytes result to output. */ 
9041-             Py_ssize_t  outsize  =  PyBytes_Size ( * res );
9039+             Py_ssize_t  outsize  =  PyBytesWriter_GetSize ( writer );
90429040            Py_ssize_t  requiredsize ;
90439041            repsize  =  PyBytes_Size (repunicode );
90449042            requiredsize  =  * respos  +  repsize ;
90459043            if  (requiredsize  >  outsize )
90469044                /* Make room for all additional bytes. */ 
9047-                 if  (charmapencode_resize (res , respos , requiredsize )) {
9045+                 if  (charmapencode_resize (writer , respos , requiredsize )) {
90489046                    Py_DECREF (repunicode );
90499047                    return  -1 ;
90509048                }
9051-             memcpy (PyBytes_AsString ( * res ) +  * respos ,
9049+             memcpy (PyBytesWriter_GetData ( writer ) +  * respos ,
90529050                   PyBytes_AsString (repunicode ),  repsize );
90539051            * respos  +=  repsize ;
90549052            * inpos  =  newpos ;
@@ -9061,7 +9059,7 @@ charmap_encoding_error(
90619059        kind  =  PyUnicode_KIND (repunicode );
90629060        for  (index  =  0 ; index  <  repsize ; index ++ ) {
90639061            Py_UCS4  repch  =  PyUnicode_READ (kind , data , index );
9064-             x  =  charmapencode_output (repch , mapping , res , respos );
9062+             x  =  charmapencode_output (repch , mapping , writer , respos );
90659063            if  (x == enc_EXCEPTION ) {
90669064                Py_DECREF (repunicode );
90679065                return  -1 ;
@@ -9083,8 +9081,6 @@ _PyUnicode_EncodeCharmap(PyObject *unicode,
90839081                         PyObject  * mapping ,
90849082                         const  char  * errors )
90859083{
9086-     /* output object */ 
9087-     PyObject  * res  =  NULL ;
90889084    /* current input position */ 
90899085    Py_ssize_t  inpos  =  0 ;
90909086    Py_ssize_t  size ;
@@ -9097,32 +9093,36 @@ _PyUnicode_EncodeCharmap(PyObject *unicode,
90979093    int  kind ;
90989094
90999095    size  =  PyUnicode_GET_LENGTH (unicode );
9096+     if  (size  ==  0 ) {
9097+         return  Py_GetConstant (Py_CONSTANT_EMPTY_BYTES );
9098+     }
91009099    data  =  PyUnicode_DATA (unicode );
91019100    kind  =  PyUnicode_KIND (unicode );
91029101
91039102    /* Default to Latin-1 */ 
91049103    if  (mapping  ==  NULL )
91059104        return  unicode_encode_ucs1 (unicode , errors , 256 );
91069105
9106+     /* output object */ 
9107+     PyBytesWriter  * writer ;
91079108    /* allocate enough for a simple encoding without 
91089109       replacements, if we need more, we'll resize */ 
9109-     res  =  PyBytes_FromStringAndSize ( NULL ,  size );
9110-     if  (res  ==  NULL )
9110+     writer  =  PyBytesWriter_Create ( size );
9111+     if  (writer  ==  NULL ) { 
91119112        goto onError ;
9112-     if  (size  ==  0 )
9113-         return  res ;
9113+     }
91149114
91159115    while  (inpos < size ) {
91169116        Py_UCS4  ch  =  PyUnicode_READ (kind , data , inpos );
91179117        /* try to encode it */ 
9118-         charmapencode_result  x  =  charmapencode_output (ch , mapping , & res , & respos );
9118+         charmapencode_result  x  =  charmapencode_output (ch , mapping , writer , & respos );
91199119        if  (x == enc_EXCEPTION ) /* error */ 
91209120            goto onError ;
91219121        if  (x == enc_FAILED ) { /* unencodable character */ 
91229122            if  (charmap_encoding_error (unicode , & inpos , mapping ,
91239123                                       & exc ,
91249124                                       & error_handler , & error_handler_obj , errors ,
9125-                                        & res , & respos )) {
9125+                                        writer , & respos )) {
91269126                goto onError ;
91279127            }
91289128        }
@@ -9131,17 +9131,14 @@ _PyUnicode_EncodeCharmap(PyObject *unicode,
91319131            ++ inpos ;
91329132    }
91339133
9134-     /* Resize if we allocated to much */ 
9135-     if  (respos < PyBytes_GET_SIZE (res ))
9136-         if  (_PyBytes_Resize (& res , respos ) <  0 )
9137-             goto onError ;
9138- 
91399134    Py_XDECREF (exc );
91409135    Py_XDECREF (error_handler_obj );
9141-     return  res ;
9136+ 
9137+     /* Resize if we allocated too much */ 
9138+     return  PyBytesWriter_FinishWithSize (writer , respos );
91429139
91439140  onError :
9144-     Py_XDECREF ( res );
9141+     PyBytesWriter_Discard ( writer );
91459142    Py_XDECREF (exc );
91469143    Py_XDECREF (error_handler_obj );
91479144    return  NULL ;
0 commit comments