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