@@ -32,6 +32,9 @@ const maxInt = int(math.MaxInt64)
3232
3333// A Buffer is a variable-sized buffer of bytes with [Buffer.Read] and [Buffer.Write] methods.
3434// The zero value for Buffer is an empty buffer ready to use (with default allocator).
35+ // A Buffer grows as needed when writing data, using the provided allocator.
36+ // The caller is responsible for freeing the buffer's resources
37+ // with [Buffer.Free] when done using it.
3538type Buffer struct {
3639 a mem.Allocator // memory allocator; nil falls back to default one.
3740 buf []byte // contents are the bytes buf[off : len(buf)]
@@ -384,29 +387,38 @@ func (b *Buffer) ReadString(delim byte) (string, error) {
384387 return String (b .a , slice ), err
385388}
386389
387- // NewBuffer creates and initializes a new [Buffer] using a copy of buf as its
388- // initial contents. It is intended to prepare a buffer to read existing data.
390+ // NewBuffer creates and initializes a new [Buffer] using buf as its
391+ // initial contents. The new Buffer takes ownership of buf, and the
392+ // caller should not use buf after this call. NewBuffer is intended to
393+ // prepare a Buffer to read existing data. It can also be used to set
394+ // the initial size of the internal buffer for writing. To do that,
395+ // buf should have the desired capacity but a length of zero.
396+ //
397+ // If buf was allocated with an allocator, the same allocator must be
398+ // passed to NewBuffer so that [Buffer.Free] can release it correctly.
399+ // Do not call [Buffer.Free] if buf was not heap-allocated.
400+ //
401+ // Do not provide a stack-allocated buf if you intend to write to the buffer,
402+ // as the buffer may need to grow and reallocate, which would cause free()
403+ // on a stack pointer. Only use heap-allocated slices in this case.
389404//
390405// If the allocator is nil, uses the system allocator.
391- // The caller is responsible for freeing the buffer's resources
392- // with [Buffer.Free] when done using it.
393406func NewBuffer (a mem.Allocator , buf []byte ) Buffer {
394- if buf == nil {
395- return Buffer {a : a }
396- }
397- b := mem .AllocSlice [byte ](a , len (buf ), cap (buf ))
398- copy (b , buf )
399- return Buffer {a : a , buf : b }
407+ return Buffer {a : a , buf : buf }
400408}
401409
402410// NewBufferString creates and initializes a new [Buffer] using string s as its
403411// initial contents. It is intended to prepare a buffer to read an existing string.
404412//
413+ // If s was allocated with an allocator, the same allocator must be
414+ // passed to NewBuffer so that [Buffer.Free] can release it correctly.
415+ // Do not call [Buffer.Free] if s was not heap-allocated.
416+ //
417+ // Do not provide a stack-allocated s if you intend to write to the buffer,
418+ // as the buffer may need to grow and reallocate, which would cause free()
419+ // on a stack pointer. Only use heap-allocated strings in this case.
420+ //
405421// If the allocator is nil, uses the system allocator.
406- // The caller is responsible for freeing the buffer's resources
407- // with [Buffer.Free] when done using it.
408422func NewBufferString (a mem.Allocator , s string ) Buffer {
409- buf := mem .AllocSlice [byte ](a , len (s ), len (s ))
410- copy (buf , s )
411- return Buffer {a : a , buf : buf }
423+ return Buffer {a : a , buf : []byte (s )}
412424}
0 commit comments