buffer.go raw
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 }
85