Documentation
¶
Overview ¶
Package filesystem provides virtual filesystem abstraction for TA archives.
Package filesystem provides a virtual filesystem that layers multiple archive formats (HPI, UFO, CCX, GP3) with physical files in a directory.
The VFS presents a unified view of files from multiple sources: - Archive files (.hpi, .ufo, .ccx, .gp3) - Physical files on disk
Files in archives are layered with higher-priority archives overriding lower-priority ones. Physical files always override archive files.
For multi-source layering (a base game, optional parent contexts and a writable work folder overlaid on top) see NewLayered in layered.go.
Example usage:
config := &filesystem.Config{
Extensions: []string{".hpi", ".ccx", ".gp3", ".ufo"},
}
vfs, err := filesystem.NewVirtualFileSystem("/path/to/game", config)
if err != nil {
log.Fatal(err)
}
defer func() { _ = vfs.Close() }()
// List all files
files := vfs.List()
// Open a file
reader, err := vfs.Open("units/ARMCOM.FBI")
if err != nil {
log.Fatal(err)
}
defer func() { _ = reader.Close() }()
// Walk the filesystem
_ = vfs.Walk(func(path string, info FileInfo) error {
fmt.Printf("%s (%d bytes)\n", path, info.Size)
return nil
})
Index ¶
- type Config
- type FileInfo
- type FileLayer
- type FileSystem
- type MemoryFileSystem
- func (mfs *MemoryFileSystem) AddFile(path string, content []byte)
- func (mfs *MemoryFileSystem) Close() error
- func (mfs *MemoryFileSystem) Exists(path string) bool
- func (mfs *MemoryFileSystem) List() []string
- func (mfs *MemoryFileSystem) Open(path string) (io.ReadCloser, error)
- func (mfs *MemoryFileSystem) ReadFile(path string) ([]byte, error)
- type PhysicalFileSystem
- type Source
- type SourceKind
- type VirtualFileSystem
- func (vfs *VirtualFileSystem) Archives() []string
- func (vfs *VirtualFileSystem) Close() error
- func (vfs *VirtualFileSystem) DirectoryStats(dirPath string) map[string]interface{}
- func (vfs *VirtualFileSystem) EnsureLocal(path string) error
- func (vfs *VirtualFileSystem) Exists(path string) bool
- func (vfs *VirtualFileSystem) GetFileLayers(path string) []FileLayer
- func (vfs *VirtualFileSystem) GetMD5(path string) (string, bool)
- func (vfs *VirtualFileSystem) IsDir(path string) bool
- func (vfs *VirtualFileSystem) IsLocal(path string) bool
- func (vfs *VirtualFileSystem) List() []string
- func (vfs *VirtualFileSystem) ListDir(dir string) ([]string, error)
- func (vfs *VirtualFileSystem) LocalLayerInfo(path string) (hasLocal bool, layers int)
- func (vfs *VirtualFileSystem) Open(path string) (io.ReadCloser, error)
- func (vfs *VirtualFileSystem) ReadFile(path string) ([]byte, error)
- func (vfs *VirtualFileSystem) ReadFileFromSource(path, sourceName string) ([]byte, error)
- func (vfs *VirtualFileSystem) RecursiveDirectoryStats(dirPath string) map[string]interface{}
- func (vfs *VirtualFileSystem) Remove(path string) error
- func (vfs *VirtualFileSystem) SetMetricsCallback(callback func(bytes int64))
- func (vfs *VirtualFileSystem) ShouldExclude(filePath string, isDir bool) bool
- func (vfs *VirtualFileSystem) Stat(path string) (*FileInfo, error)
- func (vfs *VirtualFileSystem) Stats() map[string]interface{}
- func (vfs *VirtualFileSystem) Walk(fn func(path string, info *FileInfo) error) error
- func (vfs *VirtualFileSystem) WriteFile(path string, data []byte) error
- type WritableFileSystem
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
This section is empty.
Types ¶
type Config ¶
type Config struct {
// Extensions specifies which archive extensions to load
// Example: []string{".hpi", ".ufo", ".ccx", ".gp3"}
// If empty, defaults to all supported formats
Extensions []string
// ExcludeDirectories is a list of directory names to ignore (case-insensitive)
// Example: []string{"Docs", "Backup"}
ExcludeDirectories []string
// ExcludeExtensions is a list of file extensions to ignore (case-insensitive)
// Example: []string{".dll", ".exe", ".ico"}
ExcludeExtensions []string
// ExcludePrefixes is a list of filename prefixes to ignore (case-insensitive)
// Example: []string{"goggame", "temp_"}
ExcludePrefixes []string
// CaseSensitive controls path matching (default: false for TA compatibility)
CaseSensitive bool
// SkipErrors continues loading even if some archives fail
SkipErrors bool
}
Config configures the virtual filesystem
type FileInfo ¶
type FileInfo struct {
Path string // Virtual path (e.g., "units/ARMCOM.FBI")
Size int64 // File size in bytes
Source string // Source (archive name or "disk")
IsDir bool // True if this is a directory
}
FileInfo provides information about a virtual file
type FileLayer ¶
type FileLayer struct {
Source string // Archive name or physical/overlay label
Priority int // Layer priority (lower = higher priority); assigned by GetFileLayers
Size int64 // File size in this layer
// contains filtered or unexported fields
}
FileLayer represents a single layer containing a file
type FileSystem ¶
type FileSystem interface {
// Open opens a file for reading
Open(path string) (io.ReadCloser, error)
// ReadFile reads the entire contents of a file
ReadFile(path string) ([]byte, error)
// Exists checks if a file exists
Exists(path string) bool
// List returns all file paths in the filesystem
List() []string
// Close closes the filesystem and releases resources
Close() error
}
FileSystem provides an abstraction for file operations
type MemoryFileSystem ¶
type MemoryFileSystem struct {
// contains filtered or unexported fields
}
MemoryFileSystem implements FileSystem for in-memory content (useful for testing)
func NewMemoryFileSystem ¶
func NewMemoryFileSystem() *MemoryFileSystem
NewMemoryFileSystem creates an in-memory filesystem
func (*MemoryFileSystem) AddFile ¶
func (mfs *MemoryFileSystem) AddFile(path string, content []byte)
AddFile adds a file to the in-memory filesystem
func (*MemoryFileSystem) Close ¶
func (mfs *MemoryFileSystem) Close() error
Close closes any resources (no-op for memory filesystem)
func (*MemoryFileSystem) Exists ¶
func (mfs *MemoryFileSystem) Exists(path string) bool
Exists checks if a file exists
func (*MemoryFileSystem) List ¶
func (mfs *MemoryFileSystem) List() []string
List returns all file paths
func (*MemoryFileSystem) Open ¶
func (mfs *MemoryFileSystem) Open(path string) (io.ReadCloser, error)
Open opens a file for reading
type PhysicalFileSystem ¶
type PhysicalFileSystem struct {
// contains filtered or unexported fields
}
PhysicalFileSystem implements FileSystem for local disk access
func NewPhysicalFileSystem ¶
func NewPhysicalFileSystem(basePath string) (*PhysicalFileSystem, error)
NewPhysicalFileSystem creates a filesystem that reads from a local directory
func (*PhysicalFileSystem) Close ¶
func (pfs *PhysicalFileSystem) Close() error
Close closes any resources (no-op for physical filesystem)
func (*PhysicalFileSystem) Exists ¶
func (pfs *PhysicalFileSystem) Exists(path string) bool
Exists checks if a file exists
func (*PhysicalFileSystem) List ¶
func (pfs *PhysicalFileSystem) List() []string
List returns all file paths (recursively walks the directory)
func (*PhysicalFileSystem) Open ¶
func (pfs *PhysicalFileSystem) Open(path string) (io.ReadCloser, error)
Open opens a file for reading
type Source ¶
type Source struct {
Kind SourceKind
Path string
// Writable marks this source as the writable overlay. At most one source
// may be writable and it must be the top (highest-priority) layer and a
// SourceLooseDir.
Writable bool
// Label overrides the FileLayer.Source label reported for this source. When
// empty, a sensible default is chosen (the directory base name, or
// "Physical Filesystem" for loose files inside a context directory).
Label string
}
Source describes one layer in a VFS stack.
type SourceKind ¶
type SourceKind int
SourceKind identifies how a layer source is loaded.
const ( // SourceContextDir is a game-install directory: its archives are loaded in // extension priority order, then its loose physical files are overlaid. SourceContextDir SourceKind = iota // SourceArchive is a single archive file. SourceArchive // SourceLooseDir is a plain directory of loose files (no archives), such as // a workspace's writable work folder. SourceLooseDir )
type VirtualFileSystem ¶
type VirtualFileSystem struct {
// contains filtered or unexported fields
}
VirtualFileSystem provides a layered view of archive and physical files.
Files are resolved through an ordered stack of sources (see NewLayered). Each file carries one FileLayer per source that contains it; the layer with the highest load sequence (the top-most source) is the active version.
func NewLayered ¶
func NewLayered(sources []Source, config *Config) (*VirtualFileSystem, error)
NewLayered creates a virtual filesystem from an ordered stack of sources. sources[0] is the highest-priority (top) layer; later entries are lower priority. Files present in more than one source resolve to the top-most one.
A single writable SourceLooseDir may be supplied as sources[0] to make the VFS support copy-on-write edits (see WriteFile/EnsureLocal/Remove).
func NewVirtualFileSystem ¶
func NewVirtualFileSystem(basePath string, config *Config) (*VirtualFileSystem, error)
NewVirtualFileSystem creates a read-only virtual filesystem over a single directory (its archives plus loose physical files). It is a thin wrapper over NewLayered for backward compatibility.
func (*VirtualFileSystem) Archives ¶
func (vfs *VirtualFileSystem) Archives() []string
Archives returns information about loaded archives
func (*VirtualFileSystem) Close ¶
func (vfs *VirtualFileSystem) Close() error
Close closes all open archives
func (*VirtualFileSystem) DirectoryStats ¶
func (vfs *VirtualFileSystem) DirectoryStats(dirPath string) map[string]interface{}
DirectoryStats returns statistics for a specific directory
func (*VirtualFileSystem) EnsureLocal ¶
func (vfs *VirtualFileSystem) EnsureLocal(path string) error
EnsureLocal guarantees that an existing file has a writable copy in the work folder (copy-on-write), so subsequent edits land in the overlay. It is a no-op if the file is already local, and errors if the file does not exist.
func (*VirtualFileSystem) Exists ¶
func (vfs *VirtualFileSystem) Exists(path string) bool
Exists checks if a file or directory exists
func (*VirtualFileSystem) GetFileLayers ¶
func (vfs *VirtualFileSystem) GetFileLayers(path string) []FileLayer
GetFileLayers returns all layers containing this file, ordered by priority (index 0 = highest priority = the active version).
func (*VirtualFileSystem) GetMD5 ¶
func (vfs *VirtualFileSystem) GetMD5(path string) (string, bool)
GetMD5 returns the MD5 hash for a file if it has been calculated Returns (hash, true) if available, ("", false) if not yet calculated
func (*VirtualFileSystem) IsDir ¶
func (vfs *VirtualFileSystem) IsDir(path string) bool
IsDir checks if a path is a directory
func (*VirtualFileSystem) IsLocal ¶
func (vfs *VirtualFileSystem) IsLocal(path string) bool
IsLocal reports whether a path is backed by the writable overlay layer (either net-new or an override of a base-layer file).
func (*VirtualFileSystem) List ¶
func (vfs *VirtualFileSystem) List() []string
List returns all files in the VFS
func (*VirtualFileSystem) ListDir ¶
func (vfs *VirtualFileSystem) ListDir(dir string) ([]string, error)
ListDir returns files in a specific directory
func (*VirtualFileSystem) LocalLayerInfo ¶
func (vfs *VirtualFileSystem) LocalLayerInfo(path string) (hasLocal bool, layers int)
LocalLayerInfo reports whether the path has a copy in the writable layer (i.e. Remove would succeed) and how many layers carry it in total. A deletable file with more than one layer is an OVERRIDE — removing it reverts to the base version rather than erasing the path.
func (*VirtualFileSystem) Open ¶
func (vfs *VirtualFileSystem) Open(path string) (io.ReadCloser, error)
Open opens a file for reading
func (*VirtualFileSystem) ReadFile ¶
func (vfs *VirtualFileSystem) ReadFile(path string) ([]byte, error)
ReadFile reads an entire file into memory
func (*VirtualFileSystem) ReadFileFromSource ¶
func (vfs *VirtualFileSystem) ReadFileFromSource(path, sourceName string) ([]byte, error)
ReadFileFromSource reads a file from a specific source layer. sourceName can be the physical/overlay label or an archive name like "totala1.hpi".
func (*VirtualFileSystem) RecursiveDirectoryStats ¶
func (vfs *VirtualFileSystem) RecursiveDirectoryStats(dirPath string) map[string]interface{}
RecursiveDirectoryStats returns statistics for a directory and all subdirectories
func (*VirtualFileSystem) Remove ¶
func (vfs *VirtualFileSystem) Remove(path string) error
Remove deletes a path from the writable overlay. Per the no-whiteout rule:
- a net-new local file is removed entirely;
- an override reverts to the underlying base version;
- a file that exists only in a read-only base layer cannot be removed.
func (*VirtualFileSystem) SetMetricsCallback ¶
func (vfs *VirtualFileSystem) SetMetricsCallback(callback func(bytes int64))
SetMetricsCallback sets a callback function for tracking bytes read
func (*VirtualFileSystem) ShouldExclude ¶
func (vfs *VirtualFileSystem) ShouldExclude(filePath string, isDir bool) bool
ShouldExclude checks if a file/directory should be excluded based on config
func (*VirtualFileSystem) Stat ¶
func (vfs *VirtualFileSystem) Stat(path string) (*FileInfo, error)
Stat returns information about a file
func (*VirtualFileSystem) Stats ¶
func (vfs *VirtualFileSystem) Stats() map[string]interface{}
Stats returns statistics about the VFS
type WritableFileSystem ¶
type WritableFileSystem interface {
FileSystem
// WriteFile writes data to the writable overlay, overriding any lower-layer
// version of the same path. Fails if the filesystem is read-only.
WriteFile(path string, data []byte) error
// Remove deletes a path from the writable overlay: a net-new local file is
// removed, an override reverts to the base version, and a base-only file
// cannot be removed.
Remove(path string) error
// EnsureLocal copies an existing file into the writable overlay so that
// later edits are local (copy-on-write). No-op if already local.
EnsureLocal(path string) error
// IsLocal reports whether a path is backed by the writable overlay layer.
IsLocal(path string) bool
}
WritableFileSystem is a FileSystem with a writable overlay layer, used by editing workspaces. Writes land in a local work folder layered on top of one or more read-only base layers (copy-on-write).