cache: Implement RangeOption #1825

This commit is contained in:
Nick Craig-Wood 2018-01-22 19:44:55 +00:00
parent a6833b68ca
commit 88e0770f2d
2 changed files with 29 additions and 4 deletions

View File

@ -14,6 +14,7 @@ import (
"github.com/ncw/rclone/fs"
"github.com/ncw/rclone/fs/hash"
"github.com/ncw/rclone/lib/readers"
)
// Object is a generic file like object that stores basic information about it
@ -219,19 +220,21 @@ func (o *Object) Open(options ...fs.OpenOption) (io.ReadCloser, error) {
var err error
cacheReader := NewObjectHandle(o)
var offset, limit int64
for _, option := range options {
switch x := option.(type) {
case *fs.SeekOption:
_, err = cacheReader.Seek(x.Offset, os.SEEK_SET)
offset, limit = x.Offset, 0
case *fs.RangeOption:
_, err = cacheReader.Seek(x.Start, os.SEEK_SET)
offset, limit = x.Decode(o.Size())
}
_, err = cacheReader.Seek(offset, os.SEEK_SET)
if err != nil {
return cacheReader, err
return nil, err
}
}
return cacheReader, nil
return readers.NewLimitedReadCloser(cacheReader, limit), nil
}
// Update will change the object data

22
lib/readers/limited.go Normal file
View File

@ -0,0 +1,22 @@
package readers
import "io"
// LimitedReadCloser adds io.Closer to io.LimitedReader. Create one with NewLimitedReadCloser
type LimitedReadCloser struct {
*io.LimitedReader
io.Closer
}
// NewLimitedReadCloser returns a LimitedReadCloser wrapping rc to
// limit it to reading limit bytes. If limit == 0 then it does not
// wrap rc, it just returns it.
func NewLimitedReadCloser(rc io.ReadCloser, limit int64) (lrc io.ReadCloser) {
if limit == 0 {
return rc
}
return &LimitedReadCloser{
LimitedReader: &io.LimitedReader{R: rc, N: limit},
Closer: rc,
}
}