flexbuf

package module
v0.14.1 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jul 9, 2025 License: BSD-2-Clause Imports: 4 Imported by: 1

README

Flexible bytes buffer

Go Report Card GoDoc

Package flexbuf provides bytes buffer implementing many data access and manipulation interfaces.

io.Writer
io.WriterAt
io.ByteWriter
io.WriterTo
io.StringWriter
io.Reader
io.ByteReader
io.ReaderAt
io.ReaderFrom
io.Seeker
io.Closer
fmt.Stringer

Additionally, flexbuf provides Truncate(size int64) error method to make it almost a drop in replacement for os.File.

Installation

go get github.com/rzajac/flexbuf

Examples

buf := &flexbuf.Buffer{}

_, _ = buf.Write([]byte{0, 1, 2, 3})
_, _ = buf.Seek(-2, io.SeekEnd)
_, _ = buf.Write([]byte{4, 5})
_, _ = buf.Seek(0, io.SeekStart)

data, _ := ioutil.ReadAll(buf)
fmt.Println(data)

// Output: [0 1 4 5]

How is it different from bytes.Buffer?

The bytes.Buffer always reads from current offset and writes to the end of the buffer, flexbuf behaves more like a file it reads and writes at current offset. Also bytes.Buffer doesn't implement interfaces:

  • io.WriterAt
  • io.ReaderAt
  • io.Seeker
  • io.Closer

or methods:

  • Truncate

Can I use flexbuf.Buffer as a replacement for os.File?

It depends. Even though flexbuf.Buffer probably implements all the methods you need to use it as a replacement for os.File there are some minor differences:

  • Truncate method does not return os.PathError instances.
  • WriteAt will not return error when used on an instance created with flexbuf.New(flexbuf.Append) or flexbuf.With(myBuf, flexbuf.Append).

Benchmarks

Some benchmarks between flexbuf.Buffer and bytes.Buffer:

BenchmarkWrite/flexbuf-12          124060         11014 ns/op       32768 B/op           1 allocs/op
BenchmarkWrite/bytes-12            101112         11767 ns/op       32768 B/op           1 allocs/op
BenchmarkWriteByte/flexbuf-12    38088462          31.2 ns/op           1 B/op           1 allocs/op
BenchmarkWriteByte/bytes-12      15355932          76.9 ns/op          64 B/op           1 allocs/op
BenchmarkWriteString/flexbuf-12  18013146          63.8 ns/op          16 B/op           1 allocs/op
BenchmarkWriteString/bytes-12    12852244          88.3 ns/op          64 B/op           1 allocs/op
BenchmarkReadFrom/flexbuf-12        27813         43573 ns/op      129024 B/op           7 allocs/op
BenchmarkReadFrom/bytes-12          27439         43440 ns/op      129024 B/op           7 allocs/op

License

BSD-2-Clause

Documentation

Index

Examples

Constants

This section is empty.

Variables

View Source
var ErrOutOfBounds = errors.New("offset out of bounds")

ErrOutOfBounds is returned for invalid offsets.

Functions

func Append

func Append(buf *Buffer)

Append is the constructor option setting the initial offset to the end of the buffer. Also when Truncate is used the offset will be set to the end of the buffer. Append should be the last option on the option list.

func Offset

func Offset(off int) func(*Buffer)

Offset is the constructor option setting the initial buffer offset to off.

Types

type Buffer

type Buffer struct {
	// contains filtered or unexported fields
}

A Buffer is a variable-sized buffer of bytes. The zero value for Buffer is an empty buffer ready to use.

Example
package main

import (
	"fmt"
	"io"

	"github.com/rzajac/flexbuf"
)

func main() {
	buf := &flexbuf.Buffer{}

	_, _ = buf.Write([]byte{0, 1, 2, 3})
	_, _ = buf.Seek(-2, io.SeekEnd)
	_, _ = buf.Write([]byte{4, 5})
	_, _ = buf.Seek(0, io.SeekStart)

	data, _ := io.ReadAll(buf)
	fmt.Println(data)

}
Output:

[0 1 4 5]

func New

func New(opts ...func(buffer *Buffer)) *Buffer

New returns new instance of the Buffer. The difference between New and using zero value buffer is that New will initialize buffer with capacity of bytes.MinRead. It will panic with ErrOutOfBounds if option sets offset as negative number or greater then bytes.MinRead.

func With

func With(data []byte, opts ...func(*Buffer)) *Buffer

With creates new instance of Buffer initialized with data. The new Buffer takes ownership of buf, and the caller should not use buf after this call. NewBuffer is intended to prepare a Buffer to read existing data. It can also be used to set the initial size of the internal buffer for writing. To do that, buf should have the desired capacity but a length of zero. It will panic with ErrOutOfBounds if option sets offset as negative number or beyond buffer length.

func (*Buffer) Cap

func (b *Buffer) Cap() int

Cap returns the capacity of the buffer's underlying byte slice, that is, the total space allocated for the buffer's data.

func (*Buffer) Close

func (b *Buffer) Close() error

Close sets offset to zero and zero put the buffer. It always returns nil error.

func (*Buffer) Grow added in v0.7.0

func (b *Buffer) Grow(n int)

Grow grows the buffer's capacity, if necessary, to guarantee space for another n bytes. After Grow(n), at least n bytes can be written to the buffer without another allocation. If n is negative, Grow will panic. If the buffer can't grow it will panic with ErrTooLarge.

func (*Buffer) Len

func (b *Buffer) Len() int

Len returns the number of bytes in the buffer.

func (*Buffer) Offset

func (b *Buffer) Offset() int

Offset returns the current offset.

func (*Buffer) Read

func (b *Buffer) Read(p []byte) (int, error)

Read reads the next len(p) bytes from the buffer or until the buffer is drained. The return value 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 (*Buffer) ReadAt

func (b *Buffer) ReadAt(p []byte, off int64) (int, error)

ReadAt reads len(p) bytes from the buffer starting at byte offset off. It returns the number of bytes read and the error, if any. ReadAt always returns a non-nil error when n < len(p). It does not change the offset.

func (*Buffer) ReadByte added in v0.3.0

func (b *Buffer) ReadByte() (byte, error)

ReadByte reads and returns the next byte from the buffer or any error encountered. If ReadByte returns an error, no input byte was consumed, and the returned byte value is undefined.

func (*Buffer) ReadFrom

func (b *Buffer) ReadFrom(r io.Reader) (int64, error)

ReadFrom reads data from r until EOF and appends it to the buffer at b.off, growing the buffer as needed. The return value is the number of bytes read. Any error except io.EOF encountered during the read is also returned. If the buffer becomes too large, ReadFrom will panic with ErrTooLarge.

func (*Buffer) Release added in v0.11.0

func (b *Buffer) Release() []byte

Release releases ownership of the underlying buffer, the caller should not use the instance of Buffer after this call.

func (*Buffer) Seek

func (b *Buffer) Seek(offset int64, whence int) (int64, error)

Seek sets the offset for the next Read or Write on the buffer to offset, interpreted according to whence: 0 means relative to the origin of the file, 1 means relative to the current offset, and 2 means relative to the end. It returns the new offset and an error (only if calculated offset < 0).

func (*Buffer) SeekEnd added in v0.14.0

func (b *Buffer) SeekEnd() int64

SeekEnd is a convenience method setting the buffer's offset to the buffer length and returning the value it had before the method was called.

func (*Buffer) SeekStart added in v0.6.0

func (b *Buffer) SeekStart() int64

SeekStart is a convenience method setting the buffer's offset to zero and returning the value it had before the method was called.

func (*Buffer) String added in v0.4.0

func (b *Buffer) String() string

String returns string representation of the buffer starting at current offset. Calling this method is considered as reading the buffer and advances offset to the end of the buffer.

func (*Buffer) Truncate

func (b *Buffer) Truncate(size int64) error

Truncate changes the size of the buffer discarding bytes at offsets greater then size. It does not change the offset unless Append option was used then it sets offset to the end of the buffer. It returns error os.ErrInvalid only when when size is negative.

func (*Buffer) Write

func (b *Buffer) Write(p []byte) (int, error)

Write writes the contents of p to the buffer at current offset, growing the buffer as needed. The return value n is the length of p; err is always nil.

func (*Buffer) WriteAt

func (b *Buffer) WriteAt(p []byte, off int64) (int, error)

WriteAt writes len(p) bytes to the buffer starting at byte offset off. It returns the number of bytes written; err is always nil. It does not change the offset.

func (*Buffer) WriteByte added in v0.3.0

func (b *Buffer) WriteByte(c byte) error

WriteByte writes single byte c to the buffer.

func (*Buffer) WriteString added in v0.4.0

func (b *Buffer) WriteString(s string) (int, error)

WriteString writes string s to the buffer at the current offset.

func (*Buffer) WriteTo added in v0.4.0

func (b *Buffer) WriteTo(w io.Writer) (int64, error)

WriteTo writes data to w starting at current offset until there's no more data to write or when an error occurs. The return value n is the number of bytes written. Any error encountered during the write is also returned.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL