buffer.go raw

   1  // Copyright (c) 2016 Uber Technologies, Inc.
   2  //
   3  // Permission is hereby granted, free of charge, to any person obtaining a copy
   4  // of this software and associated documentation files (the "Software"), to deal
   5  // in the Software without restriction, including without limitation the rights
   6  // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
   7  // copies of the Software, and to permit persons to whom the Software is
   8  // furnished to do so, subject to the following conditions:
   9  //
  10  // The above copyright notice and this permission notice shall be included in
  11  // all copies or substantial portions of the Software.
  12  //
  13  // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  14  // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  15  // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  16  // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  17  // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  18  // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  19  // THE SOFTWARE.
  20  
  21  // Package buffer provides a thin wrapper around a byte slice. Unlike the
  22  // standard library's bytes.Buffer, it supports a portion of the strconv
  23  // package's zero-allocation formatters.
  24  package buffer // import "go.uber.org/zap/buffer"
  25  
  26  import (
  27  	"strconv"
  28  	"time"
  29  )
  30  
  31  const _size = 1024 // by default, create 1 KiB buffers
  32  
  33  // Buffer is a thin wrapper around a byte slice. It's intended to be pooled, so
  34  // the only way to construct one is via a Pool.
  35  type Buffer struct {
  36  	bs   []byte
  37  	pool Pool
  38  }
  39  
  40  // AppendByte writes a single byte to the Buffer.
  41  func (b *Buffer) AppendByte(v byte) {
  42  	b.bs = append(b.bs, v)
  43  }
  44  
  45  // AppendBytes writes the given slice of bytes to the Buffer.
  46  func (b *Buffer) AppendBytes(v []byte) {
  47  	b.bs = append(b.bs, v...)
  48  }
  49  
  50  // AppendString writes a string to the Buffer.
  51  func (b *Buffer) AppendString(s string) {
  52  	b.bs = append(b.bs, s...)
  53  }
  54  
  55  // AppendInt appends an integer to the underlying buffer (assuming base 10).
  56  func (b *Buffer) AppendInt(i int64) {
  57  	b.bs = strconv.AppendInt(b.bs, i, 10)
  58  }
  59  
  60  // AppendTime appends the time formatted using the specified layout.
  61  func (b *Buffer) AppendTime(t time.Time, layout string) {
  62  	b.bs = t.AppendFormat(b.bs, layout)
  63  }
  64  
  65  // AppendUint appends an unsigned integer to the underlying buffer (assuming
  66  // base 10).
  67  func (b *Buffer) AppendUint(i uint64) {
  68  	b.bs = strconv.AppendUint(b.bs, i, 10)
  69  }
  70  
  71  // AppendBool appends a bool to the underlying buffer.
  72  func (b *Buffer) AppendBool(v bool) {
  73  	b.bs = strconv.AppendBool(b.bs, v)
  74  }
  75  
  76  // AppendFloat appends a float to the underlying buffer. It doesn't quote NaN
  77  // or +/- Inf.
  78  func (b *Buffer) AppendFloat(f float64, bitSize int) {
  79  	b.bs = strconv.AppendFloat(b.bs, f, 'f', -1, bitSize)
  80  }
  81  
  82  // Len returns the length of the underlying byte slice.
  83  func (b *Buffer) Len() int {
  84  	return len(b.bs)
  85  }
  86  
  87  // Cap returns the capacity of the underlying byte slice.
  88  func (b *Buffer) Cap() int {
  89  	return cap(b.bs)
  90  }
  91  
  92  // Bytes returns a mutable reference to the underlying byte slice.
  93  func (b *Buffer) Bytes() []byte {
  94  	return b.bs
  95  }
  96  
  97  // String returns a string copy of the underlying byte slice.
  98  func (b *Buffer) String() string {
  99  	return string(b.bs)
 100  }
 101  
 102  // Reset resets the underlying byte slice. Subsequent writes re-use the slice's
 103  // backing array.
 104  func (b *Buffer) Reset() {
 105  	b.bs = b.bs[:0]
 106  }
 107  
 108  // Write implements io.Writer.
 109  func (b *Buffer) Write(bs []byte) (int, error) {
 110  	b.bs = append(b.bs, bs...)
 111  	return len(bs), nil
 112  }
 113  
 114  // WriteByte writes a single byte to the Buffer.
 115  //
 116  // Error returned is always nil, function signature is compatible
 117  // with bytes.Buffer and bufio.Writer
 118  func (b *Buffer) WriteByte(v byte) error {
 119  	b.AppendByte(v)
 120  	return nil
 121  }
 122  
 123  // WriteString writes a string to the Buffer.
 124  //
 125  // Error returned is always nil, function signature is compatible
 126  // with bytes.Buffer and bufio.Writer
 127  func (b *Buffer) WriteString(s string) (int, error) {
 128  	b.AppendString(s)
 129  	return len(s), nil
 130  }
 131  
 132  // TrimNewline trims any final "\n" byte from the end of the buffer.
 133  func (b *Buffer) TrimNewline() {
 134  	if i := len(b.bs) - 1; i >= 0 {
 135  		if b.bs[i] == '\n' {
 136  			b.bs = b.bs[:i]
 137  		}
 138  	}
 139  }
 140  
 141  // Free returns the Buffer to its Pool.
 142  //
 143  // Callers must not retain references to the Buffer after calling Free.
 144  func (b *Buffer) Free() {
 145  	b.pool.put(b)
 146  }
 147