diff --git a/pkg/ioutils/multireader.go b/pkg/ioutils/multireader.go index 0d2d76b479..234999bc92 100644 --- a/pkg/ioutils/multireader.go +++ b/pkg/ioutils/multireader.go @@ -97,27 +97,24 @@ func (r *multiReadSeeker) Seek(offset int64, whence int) (int64, error) { } func (r *multiReadSeeker) getReaderForOffset(offset int64) (io.ReadSeeker, int64, error) { - var rdr io.ReadSeeker - var rdrOffset int64 - for i, rdr := range r.readers { - offsetTo, err := r.getOffsetToReader(rdr) + var offsetTo int64 + + for _, rdr := range r.readers { + size, err := getReadSeekerSize(rdr) if err != nil { return nil, -1, err } - if offsetTo > offset { - rdr = r.readers[i-1] - rdrOffset = offsetTo - offset - break + if offsetTo+size > offset { + return rdr, offset - offsetTo, nil } - if rdr == r.readers[len(r.readers)-1] { - rdrOffset = offsetTo + offset - break + return rdr, offsetTo + offset, nil } + offsetTo += size } - return rdr, rdrOffset, nil + return nil, 0, nil } func (r *multiReadSeeker) getCurOffset() (int64, error) { diff --git a/pkg/ioutils/multireader_test.go b/pkg/ioutils/multireader_test.go index de495b56da..306f5b0e1f 100644 --- a/pkg/ioutils/multireader_test.go +++ b/pkg/ioutils/multireader_test.go @@ -147,3 +147,44 @@ func TestMultiReadSeekerNegativeSeek(t *testing.T) { t.Fatalf("expected %q to be %q", string(buf), expected) } } + +func TestMultiReadSeekerCurAfterSet(t *testing.T) { + str := "hello world" + s1 := strings.NewReader(str + " 1") + s2 := strings.NewReader(str + " 2") + s3 := strings.NewReader(str + " 3") + mr := MultiReadSeeker(s1, s2, s3) + + mid := int64(s1.Len() + s2.Len()/2) + + size, err := mr.Seek(mid, os.SEEK_SET) + if err != nil { + t.Fatal(err) + } + if size != mid { + t.Fatalf("reader size does not match, got %d, expected %d", size, mid) + } + + size, err = mr.Seek(3, os.SEEK_CUR) + if err != nil { + t.Fatal(err) + } + if size != mid+3 { + t.Fatalf("reader size does not match, got %d, expected %d", size, mid+3) + } + size, err = mr.Seek(5, os.SEEK_CUR) + if err != nil { + t.Fatal(err) + } + if size != mid+8 { + t.Fatalf("reader size does not match, got %d, expected %d", size, mid+8) + } + + size, err = mr.Seek(10, os.SEEK_CUR) + if err != nil { + t.Fatal(err) + } + if size != mid+18 { + t.Fatalf("reader size does not match, got %d, expected %d", size, mid+18) + } +}