Skip to content

KarpelesLab/rc

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

4 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

GoDoc Test Go Report Card License: MIT

rc

rc is a tiny, dependency-free Go package that keeps track of how many bytes have been read from a stream. It is handy when implementing io.ReaderFrom — or any method that must report a byte count — without having to thread a running total through every read call yourself.

A ReadCounter wraps an io.Reader and transparently counts every byte read through it. Because it also implements io.ByteReader, it can be passed straight to helpers such as binary.Read or binary.ReadUvarint. As a bonus, it records the call site where it was created, so the errors it produces are annotated with the originating function, file and line.

Install

go get github.com/KarpelesLab/rc

Usage

Wrap your reader with rc.New, read through the returned *ReadCounter, and return the accumulated count when you are done:

func (obj *myObject) ReadFrom(r io.Reader) (int64, error) {
    rc := rc.New(r)

    // ReadCounter implements io.Reader and io.ByteReader, so it works
    // anywhere a reader is expected.
    if err := binary.Read(rc, binary.BigEndian, &obj.Value); err != nil {
        // Error64 returns the bytes read so far plus an annotated error.
        return rc.Error64(err)
    }

    // ... more reading ...

    // Ret64 returns the total byte count with a nil error.
    return rc.Ret64()
}

When an error is returned via Error64, it is wrapped with the call site captured by New, for example:

in main.(*myObject).ReadFrom at main.go:42: unexpected EOF

The wrapped error keeps the original error reachable through errors.Is and errors.As.

API

Method Purpose
New(r io.Reader) *ReadCounter Wrap r and start counting from zero. A plain io.Reader is adapted so ReadByte works; a *ReadCounter may be nested.
Read(p []byte) (int, error) Read into p, adding the number of bytes read to the counter.
ReadByte() (byte, error) Read a single byte, incrementing the counter on success.
ReadFull(buf []byte) error Read exactly len(buf) bytes via io.ReadFull, counting them.
Ret64() (int64, error) Return the count and a nil error, shaped for io.ReaderFrom.
Ret() (int, error) Return the count and a nil error, shaped for io.Reader.
Error64(err error) (int64, error) Return the count and err annotated with the call site, shaped for io.ReaderFrom.
Error(err error) (int, error) Same as Error64, shaped for io.Reader.

Notes

  • A ReadCounter is not safe for concurrent use.
  • The zero value is not usable — always create one with New.
  • New panics if it is given a nil reader.

License

Released under the MIT License. See LICENSE for details.

About

ReadCounter, a io.ReaderFrom helper

Resources

License

Stars

Watchers

Forks

Packages

 
 
 

Contributors