diff --git a/multireader.go b/multireader.go index 3670f2b..5e082e9 100644 --- a/multireader.go +++ b/multireader.go @@ -130,6 +130,17 @@ func (mr *multiReader) Seek(offset int64, whence int) (int64, error) { return 0, errors.New("invalid whence") } +func (mr *multiReader) resetTails() error { + for i := mr.off + 1; i < len(mr.rs); i++ { + r := mr.rs[i] + if _, err := r.Seek(0, io.SeekStart); err != nil { + return err + } + r.off = 0 + } + return nil +} + func (mr *multiReader) seekStart(offset int64, start int) (int64, error) { off := int64(0) for i := 0; i < start; i++ { @@ -156,6 +167,9 @@ func (mr *multiReader) seekStart(offset int64, start int) (int64, error) { if err != nil { return 0, err } + if err := mr.resetTails(); err != nil { + return 0, err + } return off, nil } @@ -187,6 +201,9 @@ func (mr *multiReader) seekCurrent(offset int64) (int64, error) { } return mr.seekEnd(diffset, mr.off-1) } + if err := mr.resetTails(); err != nil { + return 0, err + } return off + n, nil } diff --git a/multireader_test.go b/multireader_test.go index 2ad386c..b3977b4 100644 --- a/multireader_test.go +++ b/multireader_test.go @@ -130,6 +130,33 @@ func TestMultiSeek(t *testing.T) { whence: io.SeekStart, n: int64(4), after: "ef", + }, { + reader: func() io.ReadSeekCloser { + r := testMultiReaderStrings(t, "abc", "def") + ioutil.ReadAll(r) + return r + }, + offset: int64(0), + whence: io.SeekStart, + n: int64(0), + after: "abcdef", + }, { + reader: func() io.ReadSeekCloser { + r0 := NopReadSeekCloser(strings.NewReader("abc")) + r1 := strings.NewReader("def") + d1 := Delegate(r1) + r, err := MultiReadSeekCloser(r0, d1) + if err != nil { + t.Fatal(err) + } + d1.SeekFunc = func(offset int64, whence int) (int64, error) { + return 0, errors.New("failed to reset tails") + } + return r + }, + offset: int64(0), + whence: io.SeekStart, + errstr: "failed to reset tails", }, { reader: func() io.ReadSeekCloser { // NOTE: Check single reader. @@ -204,6 +231,23 @@ func TestMultiSeek(t *testing.T) { whence: io.SeekCurrent, n: int64(0), after: "abcdefghi", + }, { + reader: func() io.ReadSeekCloser { + r0 := NopReadSeekCloser(strings.NewReader("abc")) + r1 := strings.NewReader("def") + d1 := Delegate(r1) + r, err := MultiReadSeekCloser(r0, d1) + if err != nil { + t.Fatal(err) + } + d1.SeekFunc = func(offset int64, whence int) (int64, error) { + return 0, errors.New("failed to reset tails") + } + return r + }, + offset: int64(0), + whence: io.SeekCurrent, + errstr: "failed to reset tails", }, { reader: func() io.ReadSeekCloser { // NOTE: Check single reader.