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 }