git/odb/pack: teach *OffsetReaderAt to handle positioned reads

This commit is contained in:
Taylor Blau 2017-09-05 17:00:18 -04:00
parent c7f13cdab2
commit 3bb7cace5b
2 changed files with 80 additions and 0 deletions

27
git/odb/pack/io.go Normal file

@ -0,0 +1,27 @@
package pack
import "io"
// OffsetReaderAt transforms an io.ReaderAt into an io.Reader by beginning and
// advancing all reads at the given offset.
type OffsetReaderAt struct {
// r is the data source for this instance of *OffsetReaderAt.
r io.ReaderAt
// o if the number of bytes read from the underlying data source, "r".
// It is incremented upon reads.
o int64
}
// Read implements io.Reader.Read by reading into the given []byte, "p" from the
// last known offset provided to the OffsetReaderAt.
//
// It returns any error encountered from the underlying data stream, and
// advances the reader forward by "n", the number of bytes read from the
// underlying data stream.
func (r *OffsetReaderAt) Read(p []byte) (n int, err error) {
n, err = r.r.ReadAt(p, r.o)
r.o += int64(n)
return n, err
}

53
git/odb/pack/io_test.go Normal file

@ -0,0 +1,53 @@
package pack
import (
"bytes"
"testing"
"github.com/git-lfs/git-lfs/errors"
"github.com/stretchr/testify/assert"
)
func TestOffsetReaderAtReadsAtOffset(t *testing.T) {
bo := &OffsetReaderAt{
r: bytes.NewReader([]byte{0x0, 0x1, 0x2, 0x3}),
o: 1,
}
var x1 [1]byte
n1, e1 := bo.Read(x1[:])
assert.NoError(t, e1)
assert.Equal(t, 1, n1)
assert.EqualValues(t, 0x1, x1[0])
var x2 [1]byte
n2, e2 := bo.Read(x2[:])
assert.NoError(t, e2)
assert.Equal(t, 1, n2)
assert.EqualValues(t, 0x2, x2[0])
}
func TestOffsetReaderPropogatesErrors(t *testing.T) {
expected := errors.New("git/odb/pack: testing")
bo := &OffsetReaderAt{
r: &ErrReaderAt{Err: expected},
o: 1,
}
n, err := bo.Read(make([]byte, 1))
assert.Equal(t, expected, err)
assert.Equal(t, 0, n)
}
type ErrReaderAt struct {
Err error
}
func (e *ErrReaderAt) ReadAt(p []byte, at int64) (n int, err error) {
return 0, e.Err
}