08044ce5ef | ||
---|---|---|
LICENSE | ||
README.md | ||
doc.go | ||
example_test.go | ||
go.mod | ||
go.sum | ||
reader.go | ||
reader_test.go | ||
val_read.go | ||
val_read_test.go | ||
val_write.go | ||
val_write_test.go | ||
writer.go | ||
writer_test.go |
README.md
src.lwithers.me.uk/go/byteio
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.