local: factor RangeOption code to Decode() method and readers.LimitedReadCloser #1825

This commit is contained in:
Nick Craig-Wood 2018-01-22 19:44:00 +00:00
parent e44dc2b14d
commit a6833b68ca
2 changed files with 20 additions and 26 deletions

View file

@ -19,6 +19,7 @@ import (
"github.com/ncw/rclone/fs/config"
"github.com/ncw/rclone/fs/config/flags"
"github.com/ncw/rclone/fs/hash"
"github.com/ncw/rclone/lib/readers"
"github.com/pkg/errors"
"google.golang.org/appengine/log"
)
@ -652,12 +653,6 @@ type localOpenFile struct {
hash *hash.MultiHasher // currently accumulating hashes
}
// limitedReadCloser adds io.Closer to io.LimitedReader
type limitedReadCloser struct {
*io.LimitedReader
io.Closer
}
// Read bytes from the object - see io.Reader
func (file *localOpenFile) Read(p []byte) (n int, err error) {
n, err = file.in.Read(p)
@ -687,20 +682,9 @@ func (o *Object) Open(options ...fs.OpenOption) (in io.ReadCloser, err error) {
for _, option := range options {
switch x := option.(type) {
case *fs.SeekOption:
offset = x.Offset
limit = 0
offset, limit = x.Offset, 0
case *fs.RangeOption:
if x.Start >= 0 {
offset = x.Start
if x.End >= 0 {
limit = x.End - x.Start + 1
} else {
limit = 0
}
} else {
offset = o.size - x.End
limit = 0
}
offset, limit = x.Decode(o.size)
case *fs.HashesOption:
hashes = x.Hashes
default:
@ -714,13 +698,7 @@ func (o *Object) Open(options ...fs.OpenOption) (in io.ReadCloser, err error) {
if err != nil {
return
}
var wrappedFd io.ReadCloser = fd
if limit != 0 {
wrappedFd = &limitedReadCloser{
LimitedReader: &io.LimitedReader{R: fd, N: limit},
Closer: fd,
}
}
wrappedFd := readers.NewLimitedReadCloser(fd, limit)
if offset != 0 {
// seek the object
_, err = fd.Seek(offset, 0)

View file

@ -62,6 +62,22 @@ func (o *RangeOption) Mandatory() bool {
return false
}
// Decode interprets the RangeOption into an offset and a limit
func (o *RangeOption) Decode(size int64) (offset, limit int64) {
if o.Start >= 0 {
offset = o.Start
if o.End >= 0 {
limit = o.End - o.Start + 1
} else {
limit = 0
}
} else {
offset = size - o.End
limit = 0
}
return offset, limit
}
// FixRangeOption looks through the slice of options and adjusts any
// RangeOption~s found that request a fetch from the end into an
// absolute fetch using the size passed in. Some remotes (eg