rclone/vendor/storj.io/uplink/download.go

82 lines
2.1 KiB
Go
Raw Normal View History

2020-05-11 20:57:46 +02:00
// Copyright (C) 2020 Storj Labs, Inc.
// See LICENSE for copying information.
package uplink
import (
"context"
"storj.io/common/storj"
"storj.io/uplink/private/stream"
)
// DownloadOptions contains additional options for downloading.
type DownloadOptions struct {
Offset int64
// When Length is negative it will read until the end of the blob.
Length int64
}
// DownloadObject starts a download from the specific key.
func (project *Project) DownloadObject(ctx context.Context, bucket, key string, options *DownloadOptions) (download *Download, err error) {
defer mon.Func().ResetTrace(&ctx)(&err)
if bucket == "" {
return nil, errwrapf("%w (%q)", ErrBucketNameInvalid, bucket)
}
if key == "" {
return nil, errwrapf("%w (%q)", ErrObjectKeyInvalid, key)
}
if options == nil {
options = &DownloadOptions{
Offset: 0,
Length: -1,
}
}
b := storj.Bucket{Name: bucket}
obj, err := project.db.GetObject(ctx, b, key)
if err != nil {
if storj.ErrNoPath.Has(err) {
return nil, errwrapf("%w (%q)", ErrObjectKeyInvalid, key)
} else if storj.ErrObjectNotFound.Has(err) {
return nil, errwrapf("%w (%q)", ErrObjectNotFound, key)
}
return nil, convertKnownErrors(err, bucket)
}
objectStream, err := project.db.GetObjectStream(ctx, b, obj)
if err != nil {
return nil, packageError.Wrap(err)
}
return &Download{
download: stream.NewDownloadRange(ctx, objectStream, project.streams, options.Offset, options.Length),
object: convertObject(&obj),
}, nil
}
// Download is a download from Storj Network.
type Download struct {
download *stream.Download
object *Object
}
// Info returns the last information about the object.
func (download *Download) Info() *Object {
return download.object
}
// Read downloads up to len(p) bytes into p from the object's data stream.
// It returns the number of bytes read (0 <= n <= len(p)) and any error encountered.
func (download *Download) Read(data []byte) (n int, err error) {
return download.download.Read(data)
}
// Close closes the reader of the download.
func (download *Download) Close() error {
return download.download.Close()
}