golang.org/x/exp@v0.0.0-20240506185415-9bf2ced13842/slog/internal/buffer/buffer.go (about)

     1  // Copyright 2022 The Go Authors. All rights reserved.
     2  // Use of this source code is governed by a BSD-style
     3  // license that can be found in the LICENSE file.
     4  
     5  // Package buffer provides a pool-allocated byte buffer.
     6  package buffer
     7  
     8  import (
     9  	"sync"
    10  )
    11  
    12  // Buffer adapted from go/src/fmt/print.go
    13  type Buffer []byte
    14  
    15  // Having an initial size gives a dramatic speedup.
    16  var bufPool = sync.Pool{
    17  	New: func() any {
    18  		b := make([]byte, 0, 1024)
    19  		return (*Buffer)(&b)
    20  	},
    21  }
    22  
    23  func New() *Buffer {
    24  	return bufPool.Get().(*Buffer)
    25  }
    26  
    27  func (b *Buffer) Free() {
    28  	// To reduce peak allocation, return only smaller buffers to the pool.
    29  	const maxBufferSize = 16 << 10
    30  	if cap(*b) <= maxBufferSize {
    31  		*b = (*b)[:0]
    32  		bufPool.Put(b)
    33  	}
    34  }
    35  
    36  func (b *Buffer) Reset() {
    37  	*b = (*b)[:0]
    38  }
    39  
    40  func (b *Buffer) Write(p []byte) (int, error) {
    41  	*b = append(*b, p...)
    42  	return len(p), nil
    43  }
    44  
    45  func (b *Buffer) WriteString(s string) {
    46  	*b = append(*b, s...)
    47  }
    48  
    49  func (b *Buffer) WriteByte(c byte) {
    50  	*b = append(*b, c)
    51  }
    52  
    53  func (b *Buffer) WritePosInt(i int) {
    54  	b.WritePosIntWidth(i, 0)
    55  }
    56  
    57  // WritePosIntWidth writes non-negative integer i to the buffer, padded on the left
    58  // by zeroes to the given width. Use a width of 0 to omit padding.
    59  func (b *Buffer) WritePosIntWidth(i, width int) {
    60  	// Cheap integer to fixed-width decimal ASCII.
    61  	// Copied from log/log.go.
    62  
    63  	if i < 0 {
    64  		panic("negative int")
    65  	}
    66  
    67  	// Assemble decimal in reverse order.
    68  	var bb [20]byte
    69  	bp := len(bb) - 1
    70  	for i >= 10 || width > 1 {
    71  		width--
    72  		q := i / 10
    73  		bb[bp] = byte('0' + i - q*10)
    74  		bp--
    75  		i = q
    76  	}
    77  	// i < 10
    78  	bb[bp] = byte('0' + i)
    79  	b.Write(bb[bp:])
    80  }
    81  
    82  func (b *Buffer) String() string {
    83  	return string(*b)
    84  }