From 3162ceaa0f7997742f8c2fce1c9660e8e86ad5bb Mon Sep 17 00:00:00 2001 From: Alan Pearce Date: Wed, 29 Jan 2025 22:00:45 +0100 Subject: use buffers as interface to storage --- internal/buffer/buffer.go | 95 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 95 insertions(+) create mode 100644 internal/buffer/buffer.go (limited to 'internal/buffer/buffer.go') diff --git a/internal/buffer/buffer.go b/internal/buffer/buffer.go new file mode 100644 index 0000000..055bf7f --- /dev/null +++ b/internal/buffer/buffer.go @@ -0,0 +1,95 @@ +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] +} -- cgit 1.4.1