@@ -219,3 +219,162 @@ called with a non-bytes parameter.
219
219
reallocation fails, the original bytes object at *\* bytes * is deallocated,
220
220
*\* bytes * is set to ``NULL ``, :exc: `MemoryError ` is set, and ``-1 `` is
221
221
returned.
222
+
223
+ PyBytesWriter
224
+ -------------
225
+
226
+ The :c:type: `PyBytesWriter ` API can be used to create a Python :class: `bytes `
227
+ object.
228
+
229
+ .. versionadded :: next
230
+
231
+ .. c :type :: PyBytesWriter
232
+
233
+ A bytes writer instance.
234
+
235
+ The API is **not thread safe **: a writer should only be used by a single
236
+ thread at the same time.
237
+
238
+ The instance must be destroyed by :c:func: `PyBytesWriter_Finish ` on
239
+ success, or :c:func: `PyBytesWriter_Discard ` on error.
240
+
241
+
242
+ Create, Finish, Discard
243
+ ^^^^^^^^^^^^^^^^^^^^^^^
244
+
245
+ .. c :function :: PyBytesWriter* PyBytesWriter_Create (Py_ssize_t size)
246
+
247
+ Create a :c:type:`PyBytesWriter` to write *size* bytes.
248
+
249
+ If *size* is greater than zero, allocate *size* bytes, and set the
250
+ writer size to *size*. The caller is responsible to write *size*
251
+ bytes using :c:func:`PyBytesWriter_GetData`.
252
+
253
+ On error, set an exception and return NULL.
254
+
255
+ *size* must be positive or zero.
256
+
257
+ .. c:function:: PyObject* PyBytesWriter_Finish(PyBytesWriter *writer)
258
+
259
+ Finish a :c:type: `PyBytesWriter ` created by
260
+ :c:func: `PyBytesWriter_Create `.
261
+
262
+ On success, return a Python :class: `bytes ` object.
263
+ On error, set an exception and return ``NULL ``.
264
+
265
+ The writer instance is invalid after the call in any case.
266
+ No API can be called on the writer after :c:func: `PyBytesWriter_Finish `.
267
+
268
+ .. c :function :: PyObject* PyBytesWriter_FinishWithSize (PyBytesWriter *writer, Py_ssize_t size)
269
+
270
+ Similar to :c:func: `PyBytesWriter_Finish `, but resize the writer
271
+ to *size * bytes before creating the :class: `bytes ` object.
272
+
273
+ .. c :function :: PyObject* PyBytesWriter_FinishWithPointer (PyBytesWriter *writer, void *buf)
274
+
275
+ Similar to :c:func: `PyBytesWriter_Finish `, but resize the writer
276
+ using *buf * pointer before creating the :class: `bytes ` object.
277
+
278
+ Set an exception and return ``NULL `` if *buf * pointer is outside the
279
+ internal buffer bounds.
280
+
281
+ Function pseudo-code::
282
+
283
+ Py_ssize_t size = (char*)buf - (char*)PyBytesWriter_GetData(writer);
284
+ return PyBytesWriter_FinishWithSize(writer, size);
285
+
286
+ .. c :function :: void PyBytesWriter_Discard (PyBytesWriter *writer)
287
+
288
+ Discard a :c:type: `PyBytesWriter ` created by :c:func: `PyBytesWriter_Create `.
289
+
290
+ Do nothing if *writer * is ``NULL ``.
291
+
292
+ The writer instance is invalid after the call.
293
+ No API can be called on the writer after :c:func: `PyBytesWriter_Discard `.
294
+
295
+ High-level API
296
+ ^^^^^^^^^^^^^^
297
+
298
+ .. c :function :: int PyBytesWriter_WriteBytes (PyBytesWriter *writer, const void *bytes, Py_ssize_t size)
299
+
300
+ Grow the *writer * internal buffer by *size * bytes,
301
+ write *size * bytes of *bytes * at the *writer * end,
302
+ and add *size * to the *writer * size.
303
+
304
+ If *size * is equal to ``-1 ``, call ``strlen(bytes) `` to get the
305
+ string length.
306
+
307
+ On success, return ``0 ``.
308
+ On error, set an exception and return ``-1 ``.
309
+
310
+ .. c :function :: int PyBytesWriter_Format (PyBytesWriter *writer, const char *format, ...)
311
+
312
+ Similar to :c:func: `PyBytes_FromFormat `, but write the output directly at
313
+ the writer end. Grow the writer internal buffer on demand. Then add the
314
+ written size to the writer size.
315
+
316
+ On success, return ``0 ``.
317
+ On error, set an exception and return ``-1 ``.
318
+
319
+
320
+ Getters
321
+ ^^^^^^^
322
+
323
+ .. c :function :: Py_ssize_t PyBytesWriter_GetSize (PyBytesWriter *writer)
324
+
325
+ Get the writer size.
326
+
327
+ .. c :function :: void * PyBytesWriter_GetData (PyBytesWriter *writer)
328
+
329
+ Get the writer data: start of the internal buffer.
330
+
331
+ The pointer is valid until :c:func: `PyBytesWriter_Finish ` or
332
+ :c:func: `PyBytesWriter_Discard ` is called on *writer *.
333
+
334
+
335
+ Low-level API
336
+ ^^^^^^^^^^^^^
337
+
338
+ .. c :function :: int PyBytesWriter_Resize (PyBytesWriter *writer, Py_ssize_t size)
339
+
340
+ Resize the writer to *size * bytes. It can be used to enlarge or to
341
+ shrink the writer.
342
+
343
+ Newly allocated bytes are left uninitialized.
344
+
345
+ On success, return ``0 ``.
346
+ On error, set an exception and return ``-1 ``.
347
+
348
+ *size * must be positive or zero.
349
+
350
+ .. c :function :: int PyBytesWriter_Grow (PyBytesWriter *writer, Py_ssize_t grow)
351
+
352
+ Resize the writer by adding *grow * bytes to the current writer size.
353
+
354
+ Newly allocated bytes are left uninitialized.
355
+
356
+ On success, return ``0 ``.
357
+ On error, set an exception and return ``-1 ``.
358
+
359
+ *size * can be negative to shrink the writer.
360
+
361
+ .. c :function :: void * PyBytesWriter_GrowAndUpdatePointer (PyBytesWriter *writer, Py_ssize_t size, void *buf)
362
+
363
+ Similar to :c:func: `PyBytesWriter_Grow `, but update also the *buf *
364
+ pointer.
365
+
366
+ The *buf * pointer is moved if the internal buffer is moved in memory.
367
+ The *buf * relative position within the internal buffer is left
368
+ unchanged.
369
+
370
+ On error, set an exception and return ``NULL ``.
371
+
372
+ *buf * must not be ``NULL ``.
373
+
374
+ Function pseudo-code::
375
+
376
+ Py_ssize_t pos = (char*)buf - (char*)PyBytesWriter_GetData(writer);
377
+ if (PyBytesWriter_Grow(writer, size) < 0) {
378
+ return NULL;
379
+ }
380
+ return (char*)PyBytesWriter_GetData(writer) + pos;
0 commit comments