package buffer
import (
"io"
)
type Buffer struct {
buf []byte
pos int
len int
}
func NewBuffer(buf []byte) *Buffer {
return &Buffer{
buf: buf,
pos: 0,
len: len(buf),
}
}
// Read implements io.Reader's Read method
// Return normal error for special io.EOF handling
func (b *Buffer) Read(p []byte) (int, error) {
if b.pos >= b.len {
return 0, io.EOF
}
n := len(p)
if n > b.len-b.pos {
n = b.len - b.pos
}
copy(p[:n], b.buf[b.pos:b.pos+n])
b.pos += n
return n, nil
}
// Write appends the contents of p to the buffer's data.
func (b *Buffer) Write(p []byte) (int, error) {
if len(b.buf) < b.len+len(p) {
newLen := b.len + len(p)
if cap(b.buf) >= newLen {
b.buf = b.buf[:newLen]
} else {
newBuf := make([]byte, newLen*2)
copy(newBuf, b.buf[:b.len])
b.buf = newBuf
}
}
copy(b.buf[b.len:], p)
b.len += len(p)
return len(p), nil
}
func (b *Buffer) Len() int {
return b.len
}
// Reset resets the buffer to be empty. The underlying array is reused if possible.
func (b *Buffer) Reset() {
b.len = 0
b.pos = 0
}
func (b *Buffer) SeekStart() error {
_, err := b.Seek(0, io.SeekStart)
return err
}
// Seek moves the read position by offset bytes relative to whence (Start, Current, End)
func (b *Buffer) Seek(offset int64, whence int) (int64, error) {
var newpos int
switch whence {
case io.SeekStart:
newpos = int(offset)
case io.SeekCurrent:
newpos = b.pos + int(offset)
case io.SeekEnd:
newpos = b.len + int(offset)
default:
return 0, io.EOF
}
if newpos < 0 {
newpos = 0
} else if newpos > b.len {
newpos = b.len
}
b.pos = newpos
return int64(newpos), nil
}
func (b *Buffer) Bytes() []byte {
return b.buf[:b.len]
}
shared/buffer/buffer.go (view raw)