60 lines
1.3 KiB
Go
60 lines
1.3 KiB
Go
|
package archive
|
||
|
|
||
|
import (
|
||
|
"context"
|
||
|
|
||
|
"git.kmsign.ru/royalcat/tstor/src/vfs"
|
||
|
"github.com/bodgit/sevenzip"
|
||
|
"github.com/royalcat/ctxio"
|
||
|
)
|
||
|
|
||
|
var _ archiveLoader = SevenZipLoader
|
||
|
|
||
|
func SevenZipLoader(ctx context.Context, archivePath string, ctxreader vfs.File, size int64) (map[string]fileEntry, error) {
|
||
|
hash, err := vfs.FileHash(ctx, ctxreader)
|
||
|
if err != nil {
|
||
|
return nil, err
|
||
|
}
|
||
|
|
||
|
reader := ctxio.IoReaderAt(ctx, ctxreader)
|
||
|
r, err := sevenzip.NewReader(reader, size)
|
||
|
if err != nil {
|
||
|
return nil, err
|
||
|
}
|
||
|
|
||
|
out := make(map[string]fileEntry)
|
||
|
for i, f := range r.File {
|
||
|
if f.FileInfo().IsDir() {
|
||
|
continue
|
||
|
}
|
||
|
|
||
|
af := func(ctx context.Context) (ctxio.ReadCloser, error) {
|
||
|
reader := ctxio.IoReaderAt(ctx, ctxreader)
|
||
|
zr, err := sevenzip.NewReader(reader, size)
|
||
|
if err != nil {
|
||
|
return nil, err
|
||
|
}
|
||
|
|
||
|
rc, err := zr.File[i].Open()
|
||
|
if err != nil {
|
||
|
return nil, err
|
||
|
}
|
||
|
|
||
|
return ctxio.WrapIoReadCloser(rc), nil
|
||
|
}
|
||
|
|
||
|
info := f.FileInfo()
|
||
|
|
||
|
rr := newRandomReaderFromLinear(archiveFileIndex{archiveHash: hash, filename: f.Name}, info.Size(), af)
|
||
|
|
||
|
out[vfs.AbsPath(f.Name)] = fileEntry{
|
||
|
FileInfo: f.FileInfo(),
|
||
|
open: func(ctx context.Context) (vfs.File, error) {
|
||
|
return newArchiveFile(info.Name(), info.Size(), rr), nil
|
||
|
},
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return out, nil
|
||
|
}
|