@@ -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