@@ -196,10 +196,11 @@ PyBytes_FromString(const char *str)
196196 return (PyObject * ) op ;
197197}
198198
199- PyObject *
200- PyBytes_FromFormatV (const char * format , va_list vargs )
199+
200+ static char *
201+ bytes_fromformat (PyBytesWriter * writer , Py_ssize_t writer_pos ,
202+ const char * format , va_list vargs )
201203{
202- char * s ;
203204 const char * f ;
204205 const char * p ;
205206 Py_ssize_t prec ;
@@ -213,21 +214,20 @@ PyBytes_FromFormatV(const char *format, va_list vargs)
213214 Longest 64-bit pointer representation:
214215 "0xffffffffffffffff\0" (19 bytes). */
215216 char buffer [21 ];
216- _PyBytesWriter writer ;
217217
218- _PyBytesWriter_Init ( & writer );
218+ char * s = ( char * ) PyBytesWriter_GetData ( writer ) + writer_pos ;
219219
220- s = _PyBytesWriter_Alloc (& writer , strlen (format ));
221- if (s == NULL )
222- return NULL ;
223- writer .overallocate = 1 ;
224-
225- #define WRITE_BYTES (str ) \
220+ #define WRITE_BYTES_LEN (str , len_expr ) \
226221 do { \
227- s = _PyBytesWriter_WriteBytes(&writer, s, (str), strlen(str)); \
228- if (s == NULL) \
222+ size_t len = (len_expr); \
223+ s = PyBytesWriter_GrowAndUpdatePointer(writer, len, s); \
224+ if (s == NULL) { \
229225 goto error; \
226+ } \
227+ memcpy(s, (str), len); \
228+ s += len; \
230229 } while (0)
230+ #define WRITE_BYTES (str ) WRITE_BYTES_LEN(str, strlen(str))
231231
232232 for (f = format ; * f ; f ++ ) {
233233 if (* f != '%' ) {
@@ -268,10 +268,6 @@ PyBytes_FromFormatV(const char *format, va_list vargs)
268268 ++ f ;
269269 }
270270
271- /* subtract bytes preallocated for the format string
272- (ex: 2 for "%s") */
273- writer .min_size -= (f - p + 1 );
274-
275271 switch (* f ) {
276272 case 'c' :
277273 {
@@ -282,7 +278,6 @@ PyBytes_FromFormatV(const char *format, va_list vargs)
282278 "expects an integer in range [0; 255]" );
283279 goto error ;
284280 }
285- writer .min_size ++ ;
286281 * s ++ = (unsigned char )c ;
287282 break ;
288283 }
@@ -341,9 +336,7 @@ PyBytes_FromFormatV(const char *format, va_list vargs)
341336 i ++ ;
342337 }
343338 }
344- s = _PyBytesWriter_WriteBytes (& writer , s , p , i );
345- if (s == NULL )
346- goto error ;
339+ WRITE_BYTES_LEN (p , i );
347340 break ;
348341 }
349342
@@ -362,31 +355,45 @@ PyBytes_FromFormatV(const char *format, va_list vargs)
362355 break ;
363356
364357 case '%' :
365- writer .min_size ++ ;
366358 * s ++ = '%' ;
367359 break ;
368360
369361 default :
370- if (* f == 0 ) {
371- /* fix min_size if we reached the end of the format string */
372- writer .min_size ++ ;
373- }
374-
375362 /* invalid format string: copy unformatted string and exit */
376363 WRITE_BYTES (p );
377- return _PyBytesWriter_Finish ( & writer , s ) ;
364+ return s ;
378365 }
379366 }
380367
381368#undef WRITE_BYTES
369+ #undef WRITE_BYTES_LEN
382370
383- return _PyBytesWriter_Finish ( & writer , s ) ;
371+ return s ;
384372
385373 error :
386- _PyBytesWriter_Dealloc (& writer );
387374 return NULL ;
388375}
389376
377+
378+ PyObject *
379+ PyBytes_FromFormatV (const char * format , va_list vargs )
380+ {
381+ Py_ssize_t alloc = strlen (format );
382+ PyBytesWriter * writer = PyBytesWriter_Create (alloc );
383+ if (writer == NULL ) {
384+ return NULL ;
385+ }
386+
387+ char * s = bytes_fromformat (writer , 0 , format , vargs );
388+ if (s == NULL ) {
389+ PyBytesWriter_Discard (writer );
390+ return NULL ;
391+ }
392+
393+ return PyBytesWriter_FinishWithPointer (writer , s );
394+ }
395+
396+
390397PyObject *
391398PyBytes_FromFormat (const char * format , ...)
392399{
@@ -399,6 +406,7 @@ PyBytes_FromFormat(const char *format, ...)
399406 return ret ;
400407}
401408
409+
402410/* Helpers for formatstring */
403411
404412Py_LOCAL_INLINE (PyObject * )
@@ -4048,3 +4056,21 @@ PyBytesWriter_WriteBytes(PyBytesWriter *writer,
40484056 memcpy (buf + pos , bytes , size );
40494057 return 0 ;
40504058}
4059+
4060+
4061+ int
4062+ PyBytesWriter_Format (PyBytesWriter * writer , const char * format , ...)
4063+ {
4064+ Py_ssize_t pos = writer -> size ;
4065+ if (PyBytesWriter_Grow (writer , strlen (format )) < 0 ) {
4066+ return -1 ;
4067+ }
4068+
4069+ va_list vargs ;
4070+ va_start (vargs , format );
4071+ char * buf = bytes_fromformat (writer , pos , format , vargs );
4072+ va_end (vargs );
4073+
4074+ Py_ssize_t size = buf - byteswriter_data (writer );
4075+ return PyBytesWriter_Resize (writer , size );
4076+ }
0 commit comments