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  }