gitee.com/gricks/utils@v1.0.8/buffer_pool.go (about) 1 package utils 2 3 import ( 4 "strconv" 5 "sync" 6 ) 7 8 // A Pool is a type-safe wrapper around a sync.Pool. 9 type BufferPool struct { 10 p *sync.Pool 11 } 12 13 // NewBufferPool constructs a new Pool. 14 func NewBufferPool(capacity int) *BufferPool { 15 return &BufferPool{p: &sync.Pool{ 16 New: func() interface{} { 17 return &Buffer{bs: make([]byte, 0, capacity)} 18 }, 19 }} 20 } 21 22 // Get retrieves a Buffer from the pool, creating one if necessary. 23 func (p *BufferPool) Get() *Buffer { 24 buf := p.p.Get().(*Buffer) 25 buf.Reset() 26 buf.pool = p 27 return buf 28 } 29 30 // Buffer is a thin wrapper around a byte slice. It's intended to be pooled, so 31 // the only way to construct one is via a Pool. 32 type Buffer struct { 33 bs []byte 34 pool *BufferPool 35 } 36 37 // AppendByte writes a single byte to the Buffer. 38 func (b *Buffer) AppendByte(v byte) *Buffer { 39 b.bs = append(b.bs, v) 40 return b 41 } 42 43 // AppendString writes a string to the Buffer. 44 func (b *Buffer) AppendString(s string) *Buffer { 45 b.bs = append(b.bs, s...) 46 return b 47 } 48 49 // AppendInt appends an integer to the underlying buffer (assuming base 10). 50 func (b *Buffer) AppendInt(i int64) *Buffer { 51 b.bs = strconv.AppendInt(b.bs, i, 10) 52 return b 53 } 54 55 // AppendUint appends an unsigned integer to the underlying buffer (assuming 56 // base 10). 57 func (b *Buffer) AppendUint(i uint64) *Buffer { 58 b.bs = strconv.AppendUint(b.bs, i, 10) 59 return b 60 } 61 62 // AppendBool appends a bool to the underlying buffer. 63 func (b *Buffer) AppendBool(v bool) *Buffer { 64 b.bs = strconv.AppendBool(b.bs, v) 65 return b 66 } 67 68 // AppendFloat appends a float to the underlying buffer. It doesn't quote NaN 69 // or +/- Inf. 70 func (b *Buffer) AppendFloat32(f float32) *Buffer { 71 b.bs = strconv.AppendFloat(b.bs, float64(f), 'f', -1, 32) 72 return b 73 } 74 75 func (b *Buffer) AppendFloat64(f float64) *Buffer { 76 b.bs = strconv.AppendFloat(b.bs, f, 'f', -1, 64) 77 return b 78 } 79 80 // Len returns the length of the underlying byte slice. 81 func (b *Buffer) Len() int { 82 return len(b.bs) 83 } 84 85 // Cap returns the capacity of the underlying byte slice. 86 func (b *Buffer) Cap() int { 87 return cap(b.bs) 88 } 89 90 // Bytes returns a mutable reference to the underlying byte slice. 91 func (b *Buffer) Bytes() []byte { 92 return b.bs 93 } 94 95 // String returns a string copy of the underlying byte slice. 96 func (b *Buffer) String() string { 97 return string(b.bs) 98 } 99 100 // Reset resets the underlying byte slice. Subsequent writes re-use the slice's 101 // backing array. 102 func (b *Buffer) Reset() *Buffer { 103 b.bs = b.bs[:0] 104 return b 105 } 106 107 // Write implements io.Writer. 108 func (b *Buffer) Write(bs []byte) (int, error) { 109 b.bs = append(b.bs, bs...) 110 return len(bs), nil 111 } 112 113 // TrimNewline trims any final "\n" byte from the end of the buffer. 114 func (b *Buffer) TrimNewline() *Buffer { 115 if i := len(b.bs) - 1; i >= 0 { 116 if b.bs[i] == '\n' { 117 b.bs = b.bs[:i] 118 } 119 } 120 return b 121 } 122 123 // Free returns the Buffer to its Pool. 124 // 125 // NOTICE: Callers must not retain references to the Buffer after calling Free. 126 func (b *Buffer) Free() { 127 b.pool.p.Put(b) 128 }