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 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 } // 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] }