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. 24package buffer // import "go.uber.org/zap/buffer" 25 26import ( 27 "strconv" 28 "time" 29) 30 31const _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. 35type Buffer struct { 36 bs []byte 37 pool Pool 38} 39 40// AppendByte writes a single byte to the Buffer. 41func (b *Buffer) AppendByte(v byte) { 42 b.bs = append(b.bs, v) 43} 44 45// AppendString writes a string to the Buffer. 46func (b *Buffer) AppendString(s string) { 47 b.bs = append(b.bs, s...) 48} 49 50// AppendInt appends an integer to the underlying buffer (assuming base 10). 51func (b *Buffer) AppendInt(i int64) { 52 b.bs = strconv.AppendInt(b.bs, i, 10) 53} 54 55// AppendTime appends the time formatted using the specified layout. 56func (b *Buffer) AppendTime(t time.Time, layout string) { 57 b.bs = t.AppendFormat(b.bs, layout) 58} 59 60// AppendUint appends an unsigned integer to the underlying buffer (assuming 61// base 10). 62func (b *Buffer) AppendUint(i uint64) { 63 b.bs = strconv.AppendUint(b.bs, i, 10) 64} 65 66// AppendBool appends a bool to the underlying buffer. 67func (b *Buffer) AppendBool(v bool) { 68 b.bs = strconv.AppendBool(b.bs, v) 69} 70 71// AppendFloat appends a float to the underlying buffer. It doesn't quote NaN 72// or +/- Inf. 73func (b *Buffer) AppendFloat(f float64, bitSize int) { 74 b.bs = strconv.AppendFloat(b.bs, f, 'f', -1, bitSize) 75} 76 77// Len returns the length of the underlying byte slice. 78func (b *Buffer) Len() int { 79 return len(b.bs) 80} 81 82// Cap returns the capacity of the underlying byte slice. 83func (b *Buffer) Cap() int { 84 return cap(b.bs) 85} 86 87// Bytes returns a mutable reference to the underlying byte slice. 88func (b *Buffer) Bytes() []byte { 89 return b.bs 90} 91 92// String returns a string copy of the underlying byte slice. 93func (b *Buffer) String() string { 94 return string(b.bs) 95} 96 97// Reset resets the underlying byte slice. Subsequent writes re-use the slice's 98// backing array. 99func (b *Buffer) Reset() { 100 b.bs = b.bs[:0] 101} 102 103// Write implements io.Writer. 104func (b *Buffer) Write(bs []byte) (int, error) { 105 b.bs = append(b.bs, bs...) 106 return len(bs), nil 107} 108 109// WriteByte writes a single byte to the Buffer. 110// 111// Error returned is always nil, function signature is compatible 112// with bytes.Buffer and bufio.Writer 113func (b *Buffer) WriteByte(v byte) error { 114 b.AppendByte(v) 115 return nil 116} 117 118// WriteString writes a string to the Buffer. 119// 120// Error returned is always nil, function signature is compatible 121// with bytes.Buffer and bufio.Writer 122func (b *Buffer) WriteString(s string) (int, error) { 123 b.AppendString(s) 124 return len(s), nil 125} 126 127// TrimNewline trims any final "\n" byte from the end of the buffer. 128func (b *Buffer) TrimNewline() { 129 if i := len(b.bs) - 1; i >= 0 { 130 if b.bs[i] == '\n' { 131 b.bs = b.bs[:i] 132 } 133 } 134} 135 136// Free returns the Buffer to its Pool. 137// 138// Callers must not retain references to the Buffer after calling Free. 139func (b *Buffer) Free() { 140 b.pool.put(b) 141} 142