From dc63ab38dc9825144e65264c84d909ef99090565 Mon Sep 17 00:00:00 2001 From: duckdoom4 <60387522+duckdoom4@users.noreply.github.com> Date: Sat, 9 Sep 2023 20:08:29 +0200 Subject: [PATCH] Add delete mode options for VFS --- .../Archives/ZipArchiveFileSystem.cs | 2 +- .../VFS/FileSystems/IFileSystem.cs | 11 ++++++++- .../VFS/FileSystems/LayeredFileSystem.cs | 23 ++++++++++++++++--- .../VFS/FileSystems/PhysicalFileSystem.cs | 2 +- .../VFS/FileSystems/ReadOnlyFileSystem.cs | 2 +- .../VFS/FileSystems/RelativeFileSystem.cs | 4 ++-- pkNX.Containers/VFS/Util/IFileSystemEntity.cs | 4 ++-- pkNX.Containers/VFS/Util/VirtualDirectory.cs | 5 ++++ pkNX.Containers/VFS/Util/VirtualFile.cs | 5 ++++ pkNX.Containers/VFS/VirtualFileSystem.cs | 4 ++-- 10 files changed, 49 insertions(+), 13 deletions(-) diff --git a/pkNX.Containers/VFS/FileSystems/Archives/ZipArchiveFileSystem.cs b/pkNX.Containers/VFS/FileSystems/Archives/ZipArchiveFileSystem.cs index 1f251b67..a47ba688 100644 --- a/pkNX.Containers/VFS/FileSystems/Archives/ZipArchiveFileSystem.cs +++ b/pkNX.Containers/VFS/FileSystems/Archives/ZipArchiveFileSystem.cs @@ -126,7 +126,7 @@ public void CreateDirectory(FileSystemPath path) ZipArchive.CreateEntry(ToEntryPath(path)); } - public void Delete(FileSystemPath path) + public void Delete(FileSystemPath path, DeleteMode mode = DeleteMode.TopMostLayer) { ZipArchiveEntry? entry = ZipArchive.GetEntry(ToEntryPath(path)); entry?.Delete(); diff --git a/pkNX.Containers/VFS/FileSystems/IFileSystem.cs b/pkNX.Containers/VFS/FileSystems/IFileSystem.cs index 1298549a..9d8a98e7 100644 --- a/pkNX.Containers/VFS/FileSystems/IFileSystem.cs +++ b/pkNX.Containers/VFS/FileSystems/IFileSystem.cs @@ -5,6 +5,14 @@ namespace pkNX.Containers.VFS; +public enum DeleteMode +{ + TopMostLayer, + TopMostWriteableLayer, + AllWritable, + All +} + public interface IFileSystem : IDisposable { bool IsReadOnly => false; @@ -53,7 +61,8 @@ public interface IFileSystem : IDisposable /// Deletes the specified file or directory. Does not throw an exception if the specified file or directory does not exist. /// /// The path and name of the file or directory to delete. - void Delete(FileSystemPath path); + /// The method to use when deleting the file or directory. + void Delete(FileSystemPath path, DeleteMode mode = DeleteMode.TopMostLayer); public void Move(FileSystemPath sourcePath, IFileSystem destinationFileSystem, FileSystemPath destinationPath) { diff --git a/pkNX.Containers/VFS/FileSystems/LayeredFileSystem.cs b/pkNX.Containers/VFS/FileSystems/LayeredFileSystem.cs index 028b74a2..139d58b3 100644 --- a/pkNX.Containers/VFS/FileSystems/LayeredFileSystem.cs +++ b/pkNX.Containers/VFS/FileSystems/LayeredFileSystem.cs @@ -212,9 +212,26 @@ public void CreateDirectory(FileSystemPath path) fs.CreateDirectory(path); } - public void Delete(FileSystemPath path) + public void Delete(FileSystemPath path, DeleteMode mode = DeleteMode.TopMostLayer) { - foreach (var fs in FileSystems.Where(fs => fs.Exists(path))) - fs.Delete(path); + switch (mode) + { + case DeleteMode.TopMostLayer: + GetFirstWhereExists(path)?.Delete(path); + break; + case DeleteMode.TopMostWriteableLayer: + GetFirstWritableWhereExists(path)?.Delete(path); + break; + case DeleteMode.AllWritable: + foreach (var fs in FileSystems.Where(fs => !fs.IsReadOnly && fs.Exists(path))) + fs.Delete(path); + break; + case DeleteMode.All: + foreach (var fs in FileSystems.Where(fs => fs.Exists(path))) + fs.Delete(path); + break; + default: + throw new ArgumentOutOfRangeException(nameof(mode), mode, null); + } } } diff --git a/pkNX.Containers/VFS/FileSystems/PhysicalFileSystem.cs b/pkNX.Containers/VFS/FileSystems/PhysicalFileSystem.cs index 82841b45..112ac6b8 100644 --- a/pkNX.Containers/VFS/FileSystems/PhysicalFileSystem.cs +++ b/pkNX.Containers/VFS/FileSystems/PhysicalFileSystem.cs @@ -102,7 +102,7 @@ public void CreateDirectory(FileSystemPath path) Directory.CreateDirectory(GetPhysicalPath(path)); } - public void Delete(FileSystemPath path) + public void Delete(FileSystemPath path, DeleteMode mode = DeleteMode.TopMostLayer) { if (path.IsFile) File.Delete(GetPhysicalPath(path)); diff --git a/pkNX.Containers/VFS/FileSystems/ReadOnlyFileSystem.cs b/pkNX.Containers/VFS/FileSystems/ReadOnlyFileSystem.cs index d5f4f28b..d3328aa7 100644 --- a/pkNX.Containers/VFS/FileSystems/ReadOnlyFileSystem.cs +++ b/pkNX.Containers/VFS/FileSystems/ReadOnlyFileSystem.cs @@ -67,7 +67,7 @@ public void CreateDirectory(FileSystemPath path) } [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void Delete(FileSystemPath path) + public void Delete(FileSystemPath path, DeleteMode mode = DeleteMode.TopMostLayer) { throw new UnauthorizedAccessException("This is a read-only filesystem."); } diff --git a/pkNX.Containers/VFS/FileSystems/RelativeFileSystem.cs b/pkNX.Containers/VFS/FileSystems/RelativeFileSystem.cs index afa26a2d..34d585a6 100644 --- a/pkNX.Containers/VFS/FileSystems/RelativeFileSystem.cs +++ b/pkNX.Containers/VFS/FileSystems/RelativeFileSystem.cs @@ -76,8 +76,8 @@ public void CreateDirectory(FileSystemPath path) } [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void Delete(FileSystemPath path) + public void Delete(FileSystemPath path, DeleteMode mode = DeleteMode.TopMostLayer) { - FileSystem.Delete(ToAbsolutePath(path)); + FileSystem.Delete(ToAbsolutePath(path), mode); } } diff --git a/pkNX.Containers/VFS/Util/IFileSystemEntity.cs b/pkNX.Containers/VFS/Util/IFileSystemEntity.cs index 9c9ed6c9..c70f2393 100644 --- a/pkNX.Containers/VFS/Util/IFileSystemEntity.cs +++ b/pkNX.Containers/VFS/Util/IFileSystemEntity.cs @@ -17,9 +17,9 @@ public void MoveTo(IFileSystem destinationFileSystem, FileSystemPath destination FileSystem.Move(Path, destinationFileSystem, destinationPath); } - public void Delete() + public void Delete(DeleteMode mode = DeleteMode.TopMostLayer) { - FileSystem.Delete(Path); + FileSystem.Delete(Path, mode); } public void Exists() diff --git a/pkNX.Containers/VFS/Util/VirtualDirectory.cs b/pkNX.Containers/VFS/Util/VirtualDirectory.cs index 4f80f5c8..2f95679f 100644 --- a/pkNX.Containers/VFS/Util/VirtualDirectory.cs +++ b/pkNX.Containers/VFS/Util/VirtualDirectory.cs @@ -18,6 +18,11 @@ public void MoveTo(VirtualDirectory destination) FileSystem.Move(Path, destination.FileSystem, destination.Path.AppendDirectory(Name)); } + public void Delete(DeleteMode mode = DeleteMode.TopMostLayer) + { + FileSystem.Delete(Path, mode); + } + internal static VirtualDirectory Create(IFileSystem fileSystem, FileSystemPath path) { if (!path.IsDirectory) diff --git a/pkNX.Containers/VFS/Util/VirtualFile.cs b/pkNX.Containers/VFS/Util/VirtualFile.cs index 7d0a037e..f3398fff 100644 --- a/pkNX.Containers/VFS/Util/VirtualFile.cs +++ b/pkNX.Containers/VFS/Util/VirtualFile.cs @@ -51,6 +51,11 @@ public void MoveTo(VirtualDirectory destination) FileSystem.Move(Path, destination.FileSystem, destination.Path.AppendFile(Name)); } + public void Delete(DeleteMode mode = DeleteMode.TopMostLayer) + { + FileSystem.Delete(Path, mode); + } + public ReadOnlySpan ReadAllBytes() { using var stream = Open(); diff --git a/pkNX.Containers/VFS/VirtualFileSystem.cs b/pkNX.Containers/VFS/VirtualFileSystem.cs index 4765d8fa..4c8b8e35 100644 --- a/pkNX.Containers/VFS/VirtualFileSystem.cs +++ b/pkNX.Containers/VFS/VirtualFileSystem.cs @@ -107,9 +107,9 @@ public void CreateDirectory(FileSystemPath path) } [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void Delete(FileSystemPath path) + public void Delete(FileSystemPath path, DeleteMode mode = DeleteMode.TopMostLayer) { var mount = GetMountPoint(path); - mount.FileSystem.Delete(path); + mount.FileSystem.Delete(path, mode); } }