@@ -196,10 +196,11 @@ PyBytes_FromString(const char *str)
196
196
return (PyObject * ) op ;
197
197
}
198
198
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 )
201
203
{
202
- char * s ;
203
204
const char * f ;
204
205
const char * p ;
205
206
Py_ssize_t prec ;
@@ -213,21 +214,20 @@ PyBytes_FromFormatV(const char *format, va_list vargs)
213
214
Longest 64-bit pointer representation:
214
215
"0xffffffffffffffff\0" (19 bytes). */
215
216
char buffer [21 ];
216
- _PyBytesWriter writer ;
217
217
218
- _PyBytesWriter_Init ( & writer );
218
+ char * s = ( char * ) PyBytesWriter_GetData ( writer ) + writer_pos ;
219
219
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 ) \
226
221
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) { \
229
225
goto error; \
226
+ } \
227
+ memcpy(s, (str), len); \
228
+ s += len; \
230
229
} while (0)
230
+ #define WRITE_BYTES (str ) WRITE_BYTES_LEN(str, strlen(str))
231
231
232
232
for (f = format ; * f ; f ++ ) {
233
233
if (* f != '%' ) {
@@ -268,10 +268,6 @@ PyBytes_FromFormatV(const char *format, va_list vargs)
268
268
++ f ;
269
269
}
270
270
271
- /* subtract bytes preallocated for the format string
272
- (ex: 2 for "%s") */
273
- writer .min_size -= (f - p + 1 );
274
-
275
271
switch (* f ) {
276
272
case 'c' :
277
273
{
@@ -282,7 +278,6 @@ PyBytes_FromFormatV(const char *format, va_list vargs)
282
278
"expects an integer in range [0; 255]" );
283
279
goto error ;
284
280
}
285
- writer .min_size ++ ;
286
281
* s ++ = (unsigned char )c ;
287
282
break ;
288
283
}
@@ -341,9 +336,7 @@ PyBytes_FromFormatV(const char *format, va_list vargs)
341
336
i ++ ;
342
337
}
343
338
}
344
- s = _PyBytesWriter_WriteBytes (& writer , s , p , i );
345
- if (s == NULL )
346
- goto error ;
339
+ WRITE_BYTES_LEN (p , i );
347
340
break ;
348
341
}
349
342
@@ -362,31 +355,45 @@ PyBytes_FromFormatV(const char *format, va_list vargs)
362
355
break ;
363
356
364
357
case '%' :
365
- writer .min_size ++ ;
366
358
* s ++ = '%' ;
367
359
break ;
368
360
369
361
default :
370
- if (* f == 0 ) {
371
- /* fix min_size if we reached the end of the format string */
372
- writer .min_size ++ ;
373
- }
374
-
375
362
/* invalid format string: copy unformatted string and exit */
376
363
WRITE_BYTES (p );
377
- return _PyBytesWriter_Finish ( & writer , s ) ;
364
+ return s ;
378
365
}
379
366
}
380
367
381
368
#undef WRITE_BYTES
369
+ #undef WRITE_BYTES_LEN
382
370
383
- return _PyBytesWriter_Finish ( & writer , s ) ;
371
+ return s ;
384
372
385
373
error :
386
- _PyBytesWriter_Dealloc (& writer );
387
374
return NULL ;
388
375
}
389
376
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
+
390
397
PyObject *
391
398
PyBytes_FromFormat (const char * format , ...)
392
399
{
@@ -399,6 +406,7 @@ PyBytes_FromFormat(const char *format, ...)
399
406
return ret ;
400
407
}
401
408
409
+
402
410
/* Helpers for formatstring */
403
411
404
412
Py_LOCAL_INLINE (PyObject * )
@@ -4048,3 +4056,21 @@ PyBytesWriter_WriteBytes(PyBytesWriter *writer,
4048
4056
memcpy (buf + pos , bytes , size );
4049
4057
return 0 ;
4050
4058
}
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