-
Notifications
You must be signed in to change notification settings - Fork 4
/
Copy pathreader.go
88 lines (81 loc) · 1.76 KB
/
reader.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
package gs
import (
"context"
"fmt"
"io"
"net/http"
"github.com/pkg/errors"
"github.com/viant/afs/base"
"google.golang.org/api/storage/v1"
)
type reader struct {
from int64
size int
call *storage.ObjectsGetCall
storager *storager
ctx context.Context
}
func (t *reader) Seek(offset int64, whence int) (int64, error) {
if whence != io.SeekStart {
return 0, fmt.Errorf("usupported whence: %v", whence)
}
if int(offset) > t.size {
return 0, io.EOF
}
t.from = offset
return 0, nil
}
func (t *reader) Read(dest []byte) (int, error) {
if int(t.from) > t.size {
return 0, errors.Errorf("index out of bound: %v, size: %v", t.from, t.size)
}
from := t.from
to := int(t.from) + len(dest) - 1
if to > t.size {
to = t.size
}
t.call.Header().Set(base.RangeHeader, fmt.Sprintf(base.RangeHeaderTmpl, from, to))
var response *http.Response
var err error
err = runWithRetries(t.ctx, func() error {
response, err = t.call.Download()
if err != nil && response != nil && response.Body != nil {
response.Body.Close()
}
return err
}, t.storager)
if err != nil {
return 0, err
}
if response == nil {
return 0, errors.New("response was empty")
}
if response.Body == nil {
return 0, errors.New("response body was empty")
}
defer response.Body.Close()
readSoFar := 0
for {
read, err := response.Body.Read(dest[readSoFar:])
if err != nil {
return 0, err
}
if read == 0 {
break
}
readSoFar += read
if readSoFar >= len(dest) {
break
}
}
return readSoFar, nil
}
// NewReadSeeker create a reader seeker
func NewReadSeeker(ctx context.Context, storager *storager, call *storage.ObjectsGetCall, size int) io.ReadSeeker {
return &reader{
ctx: ctx,
storager: storager,
call: call,
size: size,
}
}