From b8b57c9fb72d344aaaba1e0c88ee63252429b583 Mon Sep 17 00:00:00 2001 From: Alex Barney Date: Mon, 14 Jan 2019 20:37:34 -0600 Subject: [PATCH] Add LayeredFileSystem --- build/_build.csproj.DotSettings | 3 +- src/LibHac/IO/LayeredFileSystem.cs | 89 +++++++++++++++++++++ src/LibHac/IO/LayeredFileSystemDirectory.cs | 44 ++++++++++ 3 files changed, 135 insertions(+), 1 deletion(-) create mode 100644 src/LibHac/IO/LayeredFileSystem.cs create mode 100644 src/LibHac/IO/LayeredFileSystemDirectory.cs diff --git a/build/_build.csproj.DotSettings b/build/_build.csproj.DotSettings index 96e392e6..9aac7d8e 100644 --- a/build/_build.csproj.DotSettings +++ b/build/_build.csproj.DotSettings @@ -1,4 +1,4 @@ - + False Implicit Implicit @@ -17,6 +17,7 @@ True True True + True True True True diff --git a/src/LibHac/IO/LayeredFileSystem.cs b/src/LibHac/IO/LayeredFileSystem.cs new file mode 100644 index 00000000..594e2d50 --- /dev/null +++ b/src/LibHac/IO/LayeredFileSystem.cs @@ -0,0 +1,89 @@ +using System; +using System.Collections.Generic; +using System.IO; + +namespace LibHac.IO +{ + public class LayeredFileSystem : IFileSystem + { + private List Sources { get; } = new List(); + + public LayeredFileSystem(IList sourceFileSystems) + { + Sources.AddRange(sourceFileSystems); + } + + public IDirectory OpenDirectory(string path, OpenDirectoryMode mode) + { + path = PathTools.Normalize(path); + + var dirs = new List(); + + foreach (IFileSystem fs in Sources) + { + if (fs.DirectoryExists(path)) + { + dirs.Add(fs.OpenDirectory(path, mode)); + } + } + + var dir = new LayeredFileSystemDirectory(this, dirs, path, mode); + + return dir; + } + + public IFile OpenFile(string path, OpenMode mode) + { + path = PathTools.Normalize(path); + + foreach (IFileSystem fs in Sources) + { + if (fs.FileExists(path)) + { + return fs.OpenFile(path, mode); + } + } + + throw new FileNotFoundException(); + } + + public bool DirectoryExists(string path) + { + path = PathTools.Normalize(path); + + foreach (IFileSystem fs in Sources) + { + if (fs.DirectoryExists(path)) + { + return true; + } + } + + return false; + } + + public bool FileExists(string path) + { + path = PathTools.Normalize(path); + + foreach (IFileSystem fs in Sources) + { + if (fs.FileExists(path)) + { + return true; + } + } + + return false; + } + + public void Commit() { } + + public void CreateDirectory(string path) => throw new NotSupportedException(); + public void CreateFile(string path, long size) => throw new NotSupportedException(); + public void DeleteDirectory(string path) => throw new NotSupportedException(); + public void DeleteFile(string path) => throw new NotSupportedException(); + public void RenameDirectory(string srcPath, string dstPath) => throw new NotSupportedException(); + public void RenameFile(string srcPath, string dstPath) => throw new NotSupportedException(); + } +} diff --git a/src/LibHac/IO/LayeredFileSystemDirectory.cs b/src/LibHac/IO/LayeredFileSystemDirectory.cs new file mode 100644 index 00000000..8773ac1f --- /dev/null +++ b/src/LibHac/IO/LayeredFileSystemDirectory.cs @@ -0,0 +1,44 @@ +using System.Collections.Generic; +using System.Linq; + +namespace LibHac.IO +{ + public class LayeredFileSystemDirectory : IDirectory + { + public IFileSystem ParentFileSystem { get; } + + public string FullPath { get; } + public OpenDirectoryMode Mode { get; } + + private List Sources { get; } + + public LayeredFileSystemDirectory(IFileSystem fs, List sources, string path, OpenDirectoryMode mode) + { + ParentFileSystem = fs; + Sources = sources; + FullPath = path; + Mode = mode; + } + + public IEnumerable Read() + { + var returnedFiles = new HashSet(); + + foreach (IDirectory source in Sources) + { + foreach (DirectoryEntry entry in source.Read()) + { + if (returnedFiles.Contains(entry.FullPath)) continue; + + returnedFiles.Add(entry.FullPath); + yield return entry; + } + } + } + + public int GetEntryCount() + { + return Read().Count(); + } + } +}