buffer.go

 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.
 6package buffer
 7
 8import (
 9	"sync"
10)
11
12// Buffer adapted from go/src/fmt/print.go
13type Buffer []byte
14
15// Having an initial size gives a dramatic speedup.
16var bufPool = sync.Pool{
17	New: func() any {
18		b := make([]byte, 0, 1024)
19		return (*Buffer)(&b)
20	},
21}
22
23func New() *Buffer {
24	return bufPool.Get().(*Buffer)
25}
26
27func (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
36func (b *Buffer) Reset() {
37	*b = (*b)[:0]
38}
39
40func (b *Buffer) Write(p []byte) (int, error) {
41	*b = append(*b, p...)
42	return len(p), nil
43}
44
45func (b *Buffer) WriteString(s string) {
46	*b = append(*b, s...)
47}
48
49func (b *Buffer) WriteByte(c byte) {
50	*b = append(*b, c)
51}
52
53func (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.
59func (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
82func (b *Buffer) String() string {
83	return string(*b)
84}