2023-10-16 09:18:40 +00:00
|
|
|
package vfs
|
2021-11-23 12:05:49 +00:00
|
|
|
|
|
|
|
import (
|
|
|
|
"bytes"
|
2024-03-20 21:47:51 +00:00
|
|
|
"context"
|
2023-12-21 23:15:39 +00:00
|
|
|
"io/fs"
|
|
|
|
"path"
|
2024-03-28 13:09:42 +00:00
|
|
|
"time"
|
2021-11-23 12:05:49 +00:00
|
|
|
)
|
|
|
|
|
2023-10-16 09:18:40 +00:00
|
|
|
type MemoryFs struct {
|
2024-03-20 10:49:19 +00:00
|
|
|
name string
|
2023-10-16 09:18:40 +00:00
|
|
|
files map[string]*MemoryFile
|
2021-11-23 12:05:49 +00:00
|
|
|
}
|
|
|
|
|
2024-03-28 13:09:42 +00:00
|
|
|
var _ Filesystem = (*MemoryFs)(nil)
|
|
|
|
|
|
|
|
// ModTime implements Filesystem.
|
|
|
|
func (mfs *MemoryFs) ModTime() time.Time {
|
|
|
|
return time.Time{}
|
|
|
|
}
|
|
|
|
|
|
|
|
// Mode implements Filesystem.
|
|
|
|
func (mfs *MemoryFs) Mode() fs.FileMode {
|
|
|
|
return fs.ModeDir
|
|
|
|
}
|
|
|
|
|
|
|
|
// Size implements Filesystem.
|
|
|
|
func (fs *MemoryFs) Size() int64 {
|
|
|
|
return 0
|
|
|
|
}
|
|
|
|
|
|
|
|
// Sys implements Filesystem.
|
|
|
|
func (fs *MemoryFs) Sys() any {
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
|
|
|
// FsKind implements Filesystem.
|
|
|
|
func (fs *MemoryFs) FsName() string {
|
|
|
|
return "memoryfs"
|
|
|
|
}
|
|
|
|
|
2024-03-20 10:49:19 +00:00
|
|
|
// Info implements Filesystem.
|
|
|
|
func (fs *MemoryFs) Info() (fs.FileInfo, error) {
|
2024-06-02 19:53:33 +00:00
|
|
|
return NewDirInfo(fs.name), nil
|
2024-03-20 10:49:19 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// IsDir implements Filesystem.
|
|
|
|
func (fs *MemoryFs) IsDir() bool {
|
|
|
|
return true
|
|
|
|
}
|
|
|
|
|
|
|
|
// Name implements Filesystem.
|
|
|
|
func (fs *MemoryFs) Name() string {
|
|
|
|
return fs.name
|
|
|
|
}
|
|
|
|
|
|
|
|
// Type implements Filesystem.
|
|
|
|
func (mfs *MemoryFs) Type() fs.FileMode {
|
|
|
|
return fs.ModeDir
|
|
|
|
}
|
|
|
|
|
|
|
|
func NewMemoryFS(name string, files map[string]*MemoryFile) *MemoryFs {
|
2023-10-16 09:18:40 +00:00
|
|
|
return &MemoryFs{
|
2024-03-20 10:49:19 +00:00
|
|
|
name: name,
|
2023-10-16 09:18:40 +00:00
|
|
|
files: files,
|
2021-11-23 12:05:49 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2024-03-20 21:47:51 +00:00
|
|
|
func (m *MemoryFs) Open(ctx context.Context, filename string) (File, error) {
|
2024-05-19 21:24:09 +00:00
|
|
|
return GetFile(m.files, filename)
|
2021-11-23 12:05:49 +00:00
|
|
|
}
|
|
|
|
|
2024-03-20 21:47:51 +00:00
|
|
|
func (fs *MemoryFs) ReadDir(ctx context.Context, path string) ([]fs.DirEntry, error) {
|
2024-05-19 21:24:09 +00:00
|
|
|
return ListDirFromFiles(fs.files, path)
|
2023-12-21 23:15:39 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// Stat implements Filesystem.
|
2024-03-20 21:47:51 +00:00
|
|
|
func (mfs *MemoryFs) Stat(ctx context.Context, filename string) (fs.FileInfo, error) {
|
2023-12-21 23:15:39 +00:00
|
|
|
file, ok := mfs.files[filename]
|
|
|
|
if !ok {
|
|
|
|
return nil, ErrNotExist
|
|
|
|
}
|
2024-05-19 21:24:09 +00:00
|
|
|
return NewFileInfo(path.Base(filename), file.Size()), nil
|
2021-11-23 12:05:49 +00:00
|
|
|
}
|
|
|
|
|
2024-03-20 21:47:51 +00:00
|
|
|
// Unlink implements Filesystem.
|
|
|
|
func (fs *MemoryFs) Unlink(ctx context.Context, filename string) error {
|
|
|
|
return ErrNotImplemented
|
|
|
|
}
|
|
|
|
|
|
|
|
var _ File = (*MemoryFile)(nil)
|
2021-11-23 12:05:49 +00:00
|
|
|
|
|
|
|
type MemoryFile struct {
|
2023-12-21 23:15:39 +00:00
|
|
|
name string
|
2024-03-20 21:47:51 +00:00
|
|
|
data *bytes.Reader
|
2021-11-23 12:05:49 +00:00
|
|
|
}
|
|
|
|
|
2023-12-21 23:15:39 +00:00
|
|
|
func NewMemoryFile(name string, data []byte) *MemoryFile {
|
2021-11-23 12:05:49 +00:00
|
|
|
return &MemoryFile{
|
2024-03-20 21:47:51 +00:00
|
|
|
name: name,
|
|
|
|
data: bytes.NewReader(data),
|
2021-11-23 12:05:49 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2024-03-28 13:09:42 +00:00
|
|
|
// Name implements File.
|
|
|
|
func (d *MemoryFile) Name() string {
|
|
|
|
return d.name
|
|
|
|
}
|
|
|
|
|
2024-08-22 22:16:16 +00:00
|
|
|
// Seek implements File.
|
|
|
|
func (d *MemoryFile) Seek(offset int64, whence int) (int64, error) {
|
|
|
|
return d.data.Seek(offset, whence)
|
|
|
|
}
|
|
|
|
|
2024-03-28 13:09:42 +00:00
|
|
|
// Type implements File.
|
|
|
|
func (d *MemoryFile) Type() fs.FileMode {
|
2024-05-19 21:24:09 +00:00
|
|
|
return ROMode
|
2024-03-28 13:09:42 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
func (d *MemoryFile) Info() (fs.FileInfo, error) {
|
2024-05-19 21:24:09 +00:00
|
|
|
return NewFileInfo(d.name, int64(d.data.Len())), nil
|
2023-12-21 23:15:39 +00:00
|
|
|
}
|
|
|
|
|
2021-11-23 12:05:49 +00:00
|
|
|
func (d *MemoryFile) Size() int64 {
|
2024-03-20 21:47:51 +00:00
|
|
|
return int64(d.data.Len())
|
2021-11-23 12:05:49 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
func (d *MemoryFile) IsDir() bool {
|
|
|
|
return false
|
|
|
|
}
|
|
|
|
|
2024-03-20 21:47:51 +00:00
|
|
|
func (d *MemoryFile) Close(ctx context.Context) (err error) {
|
2021-11-23 12:05:49 +00:00
|
|
|
return
|
|
|
|
}
|
2024-03-20 21:47:51 +00:00
|
|
|
|
|
|
|
// Read implements File.
|
|
|
|
func (d *MemoryFile) Read(ctx context.Context, p []byte) (n int, err error) {
|
|
|
|
return d.data.Read(p)
|
|
|
|
}
|
|
|
|
|
|
|
|
// ReadAt implements File.
|
|
|
|
func (d *MemoryFile) ReadAt(ctx context.Context, p []byte, off int64) (n int, err error) {
|
|
|
|
return d.data.ReadAt(p, off)
|
|
|
|
}
|