@@ -160,7 +160,8 @@ PyUnicodeWriter_Create(Py_ssize_t length)
160160}
161161
162162
163- void PyUnicodeWriter_Discard (PyUnicodeWriter * writer )
163+ void
164+ PyUnicodeWriter_Discard (PyUnicodeWriter * writer )
164165{
165166 if (writer == NULL ) {
166167 return ;
@@ -511,8 +512,7 @@ PyUnicodeWriter_WriteASCII(PyUnicodeWriter *writer,
511512 assert (writer != NULL );
512513 _Py_AssertHoldsTstate ();
513514
514- _PyUnicodeWriter * priv_writer = (_PyUnicodeWriter * )writer ;
515- return _PyUnicodeWriter_WriteASCIIString (priv_writer , str , size );
515+ return _PyUnicodeWriter_WriteASCIIString ((_PyUnicodeWriter * )writer , str , size );
516516}
517517
518518
@@ -525,40 +525,25 @@ PyUnicodeWriter_WriteUTF8(PyUnicodeWriter *writer,
525525 size = strlen (str );
526526 }
527527
528- _PyUnicodeWriter * _writer = (_PyUnicodeWriter * )writer ;
529- Py_ssize_t old_pos = _writer -> pos ;
530- int res = _PyUnicode_DecodeUTF8Writer (_writer , str , size ,
531- _Py_ERROR_STRICT , NULL , NULL );
532- if (res < 0 ) {
533- _writer -> pos = old_pos ;
534- }
535- return res ;
528+ return _PyUnicode_DecodeUTF8Writer ((_PyUnicodeWriter * )writer , str , size ,
529+ _Py_ERROR_STRICT , NULL , NULL );
536530}
537531
538532
539533int
540534PyUnicodeWriter_DecodeUTF8Stateful (PyUnicodeWriter * writer ,
541- const char * string ,
542- Py_ssize_t length ,
535+ const char * str ,
536+ Py_ssize_t size ,
543537 const char * errors ,
544538 Py_ssize_t * consumed )
545539{
546- if (length < 0 ) {
547- length = strlen (string );
548- }
549-
550- _PyUnicodeWriter * _writer = (_PyUnicodeWriter * )writer ;
551- Py_ssize_t old_pos = _writer -> pos ;
552- int res = _PyUnicode_DecodeUTF8Writer (_writer , string , length ,
553- _Py_ERROR_UNKNOWN , errors ,
554- consumed );
555- if (res < 0 ) {
556- _writer -> pos = old_pos ;
557- if (consumed ) {
558- * consumed = 0 ;
559- }
540+ if (size < 0 ) {
541+ size = strlen (str );
560542 }
561- return res ;
543+
544+ return _PyUnicode_DecodeUTF8Writer ((_PyUnicodeWriter * )writer , str , size ,
545+ _Py_ERROR_UNKNOWN , errors ,
546+ consumed );
562547}
563548
564549
@@ -600,30 +585,55 @@ _PyUnicodeWriter_Finish(_PyUnicodeWriter *writer)
600585
601586 Py_ssize_t final_size = writer -> pos ;
602587 if (final_size == 0 ) {
588+ // Get the empty string singleton
603589 PyObject * empty = _PyUnicode_GetEmpty ();
604590 Py_XDECREF (str ); // writer->buffer can be NULL if the position is 0
605591 return empty ;
606592 }
607593
608- Py_ssize_t length = PyUnicode_GET_LENGTH (str );
594+ if (writer -> readonly ) {
595+ assert (final_size == PyUnicode_GET_LENGTH (str ));
596+ goto done ;
597+ }
598+ assert (final_size <= PyUnicode_GET_LENGTH (str ));
599+
609600 if (final_size == 1 && PyUnicode_KIND (str ) == PyUnicode_1BYTE_KIND ) {
610- assert (length >= 1 );
601+ // Get the single character singleton
602+ assert (PyUnicode_GET_LENGTH (str ) >= 1 );
611603 const Py_UCS1 * data = PyUnicode_1BYTE_DATA (str );
612604 Py_UCS1 ch = data [0 ];
613- PyObject * latin1_char = _Py_LATIN1_CHR (ch );
614605 Py_DECREF (str );
615- return latin1_char ;
606+ str = _Py_LATIN1_CHR (ch );
607+ goto done ;
608+ }
609+
610+ if (writer -> recheck_maxchar ) {
611+ Py_UCS4 maxchar = _PyUnicode_FindMaxChar (str , 0 , final_size );
612+ if (maxchar != writer -> maxchar ) {
613+ // Adjust the string kind
614+ PyObject * str2 = PyUnicode_New (final_size , maxchar );
615+ if (str2 == NULL ) {
616+ Py_DECREF (str );
617+ return NULL ;
618+ }
619+ _PyUnicode_FastCopyCharacters (str2 , 0 , str , 0 , final_size );
620+ Py_SETREF (str , str2 );
621+ goto done ;
622+ }
616623 }
617624
618- if (!writer -> readonly && length != final_size ) {
625+ if (PyUnicode_GET_LENGTH (str ) != final_size ) {
626+ // Truncate the string
619627 PyObject * str2 = _PyUnicode_ResizeCompact (str , final_size );
620628 if (str2 == NULL ) {
621629 Py_DECREF (str );
622630 return NULL ;
623631 }
624632 str = str2 ;
633+ goto done ;
625634 }
626635
636+ done :
627637 assert (_PyUnicode_CheckConsistency (str , 1 ));
628638 return str ;
629639}
0 commit comments