local: fix RangeOption support in Open #1825

This commit is contained in:
Fabian Möller 2018-01-20 20:37:38 +01:00 committed by Nick Craig-Wood
parent ea69deaa4c
commit 186f78d44f

View File

@ -652,6 +652,12 @@ type localOpenFile struct {
hash *hash.MultiHasher // currently accumulating hashes 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 // Read bytes from the object - see io.Reader
func (file *localOpenFile) Read(p []byte) (n int, err error) { func (file *localOpenFile) Read(p []byte) (n int, err error) {
n, err = file.in.Read(p) n, err = file.in.Read(p)
@ -676,11 +682,25 @@ func (file *localOpenFile) Close() (err error) {
// Open an object for read // Open an object for read
func (o *Object) Open(options ...fs.OpenOption) (in io.ReadCloser, err error) { func (o *Object) Open(options ...fs.OpenOption) (in io.ReadCloser, err error) {
var offset int64 var offset int64
var limit int64
hashes := hash.Supported hashes := hash.Supported
for _, option := range options { for _, option := range options {
switch x := option.(type) { switch x := option.(type) {
case *fs.SeekOption: case *fs.SeekOption:
offset = x.Offset offset = x.Offset
limit = 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
}
case *fs.HashesOption: case *fs.HashesOption:
hashes = x.Hashes hashes = x.Hashes
default: default:
@ -694,11 +714,18 @@ func (o *Object) Open(options ...fs.OpenOption) (in io.ReadCloser, err error) {
if err != nil { if err != nil {
return return
} }
var wrappedFd io.ReadCloser = fd
if limit != 0 {
wrappedFd = &limitedReadCloser{
LimitedReader: &io.LimitedReader{R: fd, N: limit},
Closer: fd,
}
}
if offset != 0 { if offset != 0 {
// seek the object // seek the object
_, err = fd.Seek(offset, 0) _, err = fd.Seek(offset, 0)
// don't attempt to make checksums // don't attempt to make checksums
return fd, err return wrappedFd, err
} }
hash, err := hash.NewMultiHasherTypes(hashes) hash, err := hash.NewMultiHasherTypes(hashes)
if err != nil { if err != nil {
@ -707,7 +734,7 @@ func (o *Object) Open(options ...fs.OpenOption) (in io.ReadCloser, err error) {
// Update the md5sum as we go along // Update the md5sum as we go along
in = &localOpenFile{ in = &localOpenFile{
o: o, o: o,
in: fd, in: wrappedFd,
hash: hash, hash: hash,
} }
return in, nil return in, nil