forked from TrueCloudLab/restic
Make file.Read more intelligible
This commit is contained in:
parent
3731a94367
commit
0606b9884e
1 changed files with 35 additions and 28 deletions
|
@ -275,9 +275,7 @@ type file struct {
|
|||
node *restic.Node
|
||||
|
||||
sizes []uint32
|
||||
|
||||
// cleartext contents
|
||||
clearContent [][]byte
|
||||
blobs [][]byte
|
||||
}
|
||||
|
||||
func newFile(repo *repository.Repository, node *restic.Node) (*file, error) {
|
||||
|
@ -291,10 +289,10 @@ func newFile(repo *repository.Repository, node *restic.Node) (*file, error) {
|
|||
}
|
||||
|
||||
return &file{
|
||||
repo: repo,
|
||||
node: node,
|
||||
sizes: sizes,
|
||||
clearContent: make([][]byte, len(node.Content)),
|
||||
repo: repo,
|
||||
node: node,
|
||||
sizes: sizes,
|
||||
blobs: make([][]byte, len(node.Content)),
|
||||
}, nil
|
||||
}
|
||||
|
||||
|
@ -305,37 +303,46 @@ func (f *file) Attr(ctx context.Context, a *fuse.Attr) error {
|
|||
return nil
|
||||
}
|
||||
|
||||
func (f *file) getBlobAt(i int) (blob []byte, err error) {
|
||||
if f.blobs[i] != nil {
|
||||
blob = f.blobs[i]
|
||||
} else {
|
||||
blob, err = f.repo.LoadBlob(pack.Data, f.node.Content[i])
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
f.blobs[i] = blob
|
||||
}
|
||||
|
||||
return blob, nil
|
||||
}
|
||||
|
||||
func (f *file) Read(ctx context.Context, req *fuse.ReadRequest, resp *fuse.ReadResponse) error {
|
||||
off := req.Offset
|
||||
|
||||
// Skip blobs before the offset
|
||||
startContent := 0
|
||||
for off > int64(f.sizes[startContent]) {
|
||||
off -= int64(f.sizes[startContent])
|
||||
startContent++
|
||||
}
|
||||
|
||||
content := make([]byte, req.Size)
|
||||
allContent := content
|
||||
|
||||
for i := range f.node.Content {
|
||||
if off >= int64(f.sizes[i]) {
|
||||
off -= int64(f.sizes[i])
|
||||
continue
|
||||
for i := startContent; i < len(f.sizes); i++ {
|
||||
blob, err := f.getBlobAt(i)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
var subContent []byte
|
||||
if f.clearContent[i] != nil {
|
||||
subContent = f.clearContent[i]
|
||||
} else {
|
||||
var err error
|
||||
subContent, err = f.repo.LoadBlob(pack.Data, f.node.Content[i])
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
f.clearContent[i] = subContent
|
||||
}
|
||||
|
||||
subContent = subContent[off:]
|
||||
blob = blob[off:]
|
||||
off = 0
|
||||
|
||||
var copied int
|
||||
if len(subContent) > len(content) {
|
||||
copied = copy(content[0:], subContent[:len(content)])
|
||||
if len(blob) > len(content) {
|
||||
copied = copy(content[0:], blob[:len(content)])
|
||||
} else {
|
||||
copied = copy(content[0:], subContent)
|
||||
copied = copy(content[0:], blob)
|
||||
}
|
||||
content = content[copied:]
|
||||
if len(content) == 0 {
|
||||
|
|
Loading…
Reference in a new issue