context fs
This commit is contained in:
parent
fd3beea874
commit
7b1863109c
25 changed files with 593 additions and 349 deletions
src/host/vfs
|
@ -2,6 +2,7 @@ package vfs
|
|||
|
||||
import (
|
||||
"archive/zip"
|
||||
"context"
|
||||
"io"
|
||||
"io/fs"
|
||||
"os"
|
||||
|
@ -9,56 +10,57 @@ import (
|
|||
"path/filepath"
|
||||
"strings"
|
||||
|
||||
"git.kmsign.ru/royalcat/tstor/pkg/ctxio"
|
||||
"git.kmsign.ru/royalcat/tstor/src/iio"
|
||||
"github.com/bodgit/sevenzip"
|
||||
"github.com/nwaples/rardecode/v2"
|
||||
)
|
||||
|
||||
var ArchiveFactories = map[string]FsFactory{
|
||||
".zip": func(f File) (Filesystem, error) {
|
||||
".zip": func(ctx context.Context, f File) (Filesystem, error) {
|
||||
stat, err := f.Stat()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return NewArchive(stat.Name(), f, stat.Size(), ZipLoader), nil
|
||||
return NewArchive(ctx, stat.Name(), f, stat.Size(), ZipLoader), nil
|
||||
},
|
||||
".rar": func(f File) (Filesystem, error) {
|
||||
".rar": func(ctx context.Context, f File) (Filesystem, error) {
|
||||
stat, err := f.Stat()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return NewArchive(stat.Name(), f, stat.Size(), RarLoader), nil
|
||||
return NewArchive(ctx, stat.Name(), f, stat.Size(), RarLoader), nil
|
||||
},
|
||||
".7z": func(f File) (Filesystem, error) {
|
||||
".7z": func(ctx context.Context, f File) (Filesystem, error) {
|
||||
stat, err := f.Stat()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return NewArchive(stat.Name(), f, stat.Size(), SevenZipLoader), nil
|
||||
return NewArchive(ctx, stat.Name(), f, stat.Size(), SevenZipLoader), nil
|
||||
},
|
||||
}
|
||||
|
||||
type archiveLoader func(r iio.Reader, size int64) (map[string]*archiveFile, error)
|
||||
type archiveLoader func(ctx context.Context, r ctxio.ReaderAt, size int64) (map[string]*archiveFile, error)
|
||||
|
||||
var _ Filesystem = &ArchiveFS{}
|
||||
|
||||
type ArchiveFS struct {
|
||||
name string
|
||||
|
||||
r iio.Reader
|
||||
r ctxio.ReaderAt
|
||||
|
||||
Size int64
|
||||
|
||||
files func() (map[string]File, error)
|
||||
}
|
||||
|
||||
func NewArchive(name string, r iio.Reader, size int64, loader archiveLoader) *ArchiveFS {
|
||||
func NewArchive(ctx context.Context, name string, r ctxio.ReaderAt, size int64, loader archiveLoader) *ArchiveFS {
|
||||
return &ArchiveFS{
|
||||
name: name,
|
||||
r: r,
|
||||
Size: size,
|
||||
files: OnceValueWOErr(func() (map[string]File, error) {
|
||||
zipFiles, err := loader(r, size)
|
||||
zipFiles, err := loader(ctx, r, size)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
@ -94,11 +96,11 @@ func NewArchive(name string, r iio.Reader, size int64, loader archiveLoader) *Ar
|
|||
}
|
||||
|
||||
// Unlink implements Filesystem.
|
||||
func (a *ArchiveFS) Unlink(filename string) error {
|
||||
func (a *ArchiveFS) Unlink(ctx context.Context, filename string) error {
|
||||
return ErrNotImplemented
|
||||
}
|
||||
|
||||
func (a *ArchiveFS) Open(filename string) (File, error) {
|
||||
func (a *ArchiveFS) Open(ctx context.Context, filename string) (File, error) {
|
||||
files, err := a.files()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
|
@ -107,7 +109,7 @@ func (a *ArchiveFS) Open(filename string) (File, error) {
|
|||
return getFile(files, filename)
|
||||
}
|
||||
|
||||
func (fs *ArchiveFS) ReadDir(path string) ([]fs.DirEntry, error) {
|
||||
func (fs *ArchiveFS) ReadDir(ctx context.Context, path string) ([]fs.DirEntry, error) {
|
||||
files, err := fs.files()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
|
@ -117,7 +119,7 @@ func (fs *ArchiveFS) ReadDir(path string) ([]fs.DirEntry, error) {
|
|||
}
|
||||
|
||||
// Stat implements Filesystem.
|
||||
func (afs *ArchiveFS) Stat(filename string) (fs.FileInfo, error) {
|
||||
func (afs *ArchiveFS) Stat(ctx context.Context, filename string) (fs.FileInfo, error) {
|
||||
files, err := afs.files()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
|
@ -204,7 +206,7 @@ func (d *archiveFile) IsDir() bool {
|
|||
return false
|
||||
}
|
||||
|
||||
func (d *archiveFile) Close() (err error) {
|
||||
func (d *archiveFile) Close(ctx context.Context) (err error) {
|
||||
if d.reader != nil {
|
||||
err = d.reader.Close()
|
||||
d.reader = nil
|
||||
|
@ -213,7 +215,7 @@ func (d *archiveFile) Close() (err error) {
|
|||
return
|
||||
}
|
||||
|
||||
func (d *archiveFile) Read(p []byte) (n int, err error) {
|
||||
func (d *archiveFile) Read(ctx context.Context, p []byte) (n int, err error) {
|
||||
if err := d.load(); err != nil {
|
||||
return 0, err
|
||||
}
|
||||
|
@ -221,7 +223,7 @@ func (d *archiveFile) Read(p []byte) (n int, err error) {
|
|||
return d.reader.Read(p)
|
||||
}
|
||||
|
||||
func (d *archiveFile) ReadAt(p []byte, off int64) (n int, err error) {
|
||||
func (d *archiveFile) ReadAt(ctx context.Context, p []byte, off int64) (n int, err error) {
|
||||
if err := d.load(); err != nil {
|
||||
return 0, err
|
||||
}
|
||||
|
@ -231,7 +233,9 @@ func (d *archiveFile) ReadAt(p []byte, off int64) (n int, err error) {
|
|||
|
||||
var _ archiveLoader = ZipLoader
|
||||
|
||||
func ZipLoader(reader iio.Reader, size int64) (map[string]*archiveFile, error) {
|
||||
func ZipLoader(ctx context.Context, ctxreader ctxio.ReaderAt, size int64) (map[string]*archiveFile, error) {
|
||||
reader := ctxio.IoReaderAt(ctx, ctxreader)
|
||||
|
||||
zr, err := zip.NewReader(reader, size)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
|
@ -261,7 +265,9 @@ func ZipLoader(reader iio.Reader, size int64) (map[string]*archiveFile, error) {
|
|||
|
||||
var _ archiveLoader = SevenZipLoader
|
||||
|
||||
func SevenZipLoader(reader iio.Reader, size int64) (map[string]*archiveFile, error) {
|
||||
func SevenZipLoader(ctx context.Context, ctxreader ctxio.ReaderAt, size int64) (map[string]*archiveFile, error) {
|
||||
reader := ctxio.IoReaderAt(ctx, ctxreader)
|
||||
|
||||
r, err := sevenzip.NewReader(reader, size)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
|
@ -294,8 +300,10 @@ func SevenZipLoader(reader iio.Reader, size int64) (map[string]*archiveFile, err
|
|||
|
||||
var _ archiveLoader = RarLoader
|
||||
|
||||
func RarLoader(reader iio.Reader, size int64) (map[string]*archiveFile, error) {
|
||||
r, err := rardecode.NewReader(iio.NewSeekerWrapper(reader, size))
|
||||
func RarLoader(ctx context.Context, ctxreader ctxio.ReaderAt, size int64) (map[string]*archiveFile, error) {
|
||||
reader := ctxio.IoReadSeekerWrapper(ctx, ctxreader, size)
|
||||
|
||||
r, err := rardecode.NewReader(reader)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue