context fs

This commit is contained in:
royalcat 2024-03-21 00:47:51 +03:00
parent fd3beea874
commit 7b1863109c
25 changed files with 593 additions and 349 deletions
src/host/vfs

View file

@ -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
}