1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144
|
// Package sbuf implements a byte buffer that can be wiped. The underlying
// byte slice is wiped on read before being declaimed, and when the
// buffer is closed, its storage is zeroised.
package sbuf
import "io"
func zero(in []byte, n int) {
if in == nil {
return
}
stop := n
if stop > len(in) || stop == 0 {
stop = len(in)
}
for i := 0; i < stop; i++ {
in[i] ^= in[i]
}
}
// A Buffer is a variable-sized buffer of bytes with Read and Write
// methods. The zero value for Buffer is an empty buffer ready to use.
type Buffer struct {
buf []byte
}
// NewBuffer creates a new buffer with the specified capacity.
func NewBuffer(n int) *Buffer {
return &Buffer{
buf: make([]byte, 0, n),
}
}
// NewBufferFrom creates a new buffer from the byte slice passed in. The
// original data will be wiped.
func NewBufferFrom(p []byte) *Buffer {
buf := NewBuffer(len(p))
buf.Write(p)
zero(p, len(p))
return buf
}
// Read reads the next len(p) bytes from the buffer or until the buffer
// is drained. The return value n is the number of bytes read. If the
// buffer has no data to return, err is io.EOF (unless len(p) is zero);
// otherwise it is nil.
func (buf *Buffer) Read(p []byte) (int, error) {
if len(buf.buf) == 0 {
if len(p) == 0 {
return 0, nil
}
return 0, io.EOF
}
copyLength := len(p)
if copyLength > len(buf.buf) {
copyLength = len(buf.buf)
}
copy(p, buf.buf)
zero(buf.buf, len(p))
buf.buf = buf.buf[copyLength:]
return copyLength, nil
}
// ReadByte reads the next byte from the buffer. If the buffer has no
// data to return, err is io.EOF; otherwise it is nil.
func (buf *Buffer) ReadByte() (byte, error) {
if len(buf.buf) == 0 {
return 0, io.EOF
}
c := buf.buf[0]
buf.buf[0] = 0
buf.buf = buf.buf[1:]
return c, nil
}
func (buf *Buffer) grow(n int) {
tmp := make([]byte, len(buf.buf), len(buf.buf)+n)
copy(tmp, buf.buf)
zero(buf.buf, len(buf.buf))
buf.buf = tmp
}
// Write appends the contents of p to the buffer, growing the buffer
// as needed. The return value n is the length of p; err is always nil.
func (buf *Buffer) Write(p []byte) (int, error) {
r := len(buf.buf) + len(p)
if cap(buf.buf) < r {
l := r
for {
if l > r {
break
}
l *= 2
}
buf.grow(l - cap(buf.buf))
}
buf.buf = append(buf.buf, p...)
return len(p), nil
}
// WriteByte adds the byte c to the buffer, growing the buffer as needed.
func (buf *Buffer) WriteByte(c byte) error {
r := len(buf.buf) + 1
if cap(buf.buf) < r {
l := r * 2
buf.grow(l - cap(buf.buf))
}
buf.buf = append(buf.buf, c)
return nil
}
// Close destroys and zeroises the buffer. The buffer will be re-opened
// on the next write.
func (buf *Buffer) Close() {
zero(buf.buf, len(buf.buf))
buf.buf = nil
}
// Len returns the length of the buffer.
func (buf *Buffer) Len() int {
return len(buf.buf)
}
// Cap returns the capacity of the buffer.
func (buf *Buffer) Cap() int {
return cap(buf.buf)
}
// Bytes returns the bytes currently in the buffer, and closes itself.
func (buf *Buffer) Bytes() []byte {
if buf.buf == nil {
return nil
}
p := make([]byte, buf.Len())
buf.Read(p)
buf.Close()
return p
}
|