Byte-oriented I/O interfaces and convenience methods
Go to file
Laurence Withers 08044ce5ef Initial commit; import from github.com/lwithers/pkg 2020-01-03 13:46:16 +00:00
LICENSE Initial commit; import from github.com/lwithers/pkg 2020-01-03 13:46:16 +00:00
README.md Initial commit; import from github.com/lwithers/pkg 2020-01-03 13:46:16 +00:00
doc.go Initial commit; import from github.com/lwithers/pkg 2020-01-03 13:46:16 +00:00
example_test.go Initial commit; import from github.com/lwithers/pkg 2020-01-03 13:46:16 +00:00
go.mod Initial commit; import from github.com/lwithers/pkg 2020-01-03 13:46:16 +00:00
go.sum Initial commit; import from github.com/lwithers/pkg 2020-01-03 13:46:16 +00:00
reader.go Initial commit; import from github.com/lwithers/pkg 2020-01-03 13:46:16 +00:00
reader_test.go Initial commit; import from github.com/lwithers/pkg 2020-01-03 13:46:16 +00:00
val_read.go Initial commit; import from github.com/lwithers/pkg 2020-01-03 13:46:16 +00:00
val_read_test.go Initial commit; import from github.com/lwithers/pkg 2020-01-03 13:46:16 +00:00
val_write.go Initial commit; import from github.com/lwithers/pkg 2020-01-03 13:46:16 +00:00
val_write_test.go Initial commit; import from github.com/lwithers/pkg 2020-01-03 13:46:16 +00:00
writer.go Initial commit; import from github.com/lwithers/pkg 2020-01-03 13:46:16 +00:00
writer_test.go Initial commit; import from github.com/lwithers/pkg 2020-01-03 13:46:16 +00:00

README.md

src.lwithers.me.uk/go/byteio

GoDoc

This package provides two interfaces, Reader and Writer, which capture the most common byte-oriented methods for I/O, namely Read([]byte), ReadByte() and ReadRune() (plus the equivalent writing methods). This is useful because sometimes you simply want to perform byte-oriented I/O without knowing whether you have an underlying bytes.Buffer or bufio.Reader etc.

Furthermore, as a convenience, there are functions which automatically wrap any io.Reader or io.Writer with a bufio equivalent if necessary. These allow for simple byte-oriented I/O operations on arbitrary reader / writer interfaces with minimal boilerplate.

Example of a method using the byteio.Reader interface:

func ReadUint16LE(r byteio.Reader) (uint16, error) {
	var n uint16
	if x, err := r.ReadByte(); err != nil {
		return 0, err
	} else {
		n = uint16(x)
	}
	if x, err := r.ReadByte(); err != nil {
		return 0, err
	} else {
		n |= uint16(x) << 8
	}
	return n, nil
}

Example of something calling this function:

	var r io.Reader
	// …
	br := byteio.NewReader(r)
	n, err := ReadUint16LE(br)

Example of using the writer interface:

	var w io.Writer
	// …
	bw := byteio.NewWriter(w)
	defer byteio.FlushIfNecessary(bw)
	err := WriteUint16LE(bw, 0x5432)

The byteio.FlushIfNecessary method determines whether its argument has a Flush() method or not, and if it does, calls it. This allows the caller to write non-conditional code, not having to check whether bw is a bufio.Writer (which needs a flush) or a bytes.Buffer (which does not), etc.