diff --git a/src/LibHac/Fs/DirectoryEntry.cs b/src/LibHac/Fs/DirectoryEntry.cs index 6ac23cf5..fbefb8e7 100644 --- a/src/LibHac/Fs/DirectoryEntry.cs +++ b/src/LibHac/Fs/DirectoryEntry.cs @@ -22,7 +22,8 @@ namespace LibHac.Fs public enum DirectoryEntryType { Directory, - File + File, + NotFound } [Flags] diff --git a/src/LibHac/Fs/FileSystemManager.cs b/src/LibHac/Fs/FileSystemManager.cs index 67ec628b..a6ffe2fd 100644 --- a/src/LibHac/Fs/FileSystemManager.cs +++ b/src/LibHac/Fs/FileSystemManager.cs @@ -1,4 +1,5 @@ using System; +using System.Collections.Generic; using LibHac.Fs.Accessors; using static LibHac.Results; @@ -26,7 +27,10 @@ namespace LibHac.Fs public void CreateDirectory(string path) { - throw new NotImplementedException(); + FindFileSystem(path.AsSpan(), out FileSystemAccessor fileSystem, out ReadOnlySpan subPath) + .ThrowIfFailure(); + + fileSystem.CreateDirectory(subPath.ToString()); } public void CreateFile(string path, long size) @@ -44,38 +48,74 @@ namespace LibHac.Fs public void DeleteDirectory(string path) { - throw new NotImplementedException(); + FindFileSystem(path.AsSpan(), out FileSystemAccessor fileSystem, out ReadOnlySpan subPath) + .ThrowIfFailure(); + + fileSystem.DeleteDirectory(subPath.ToString()); } public void DeleteDirectoryRecursively(string path) { - throw new NotImplementedException(); + FindFileSystem(path.AsSpan(), out FileSystemAccessor fileSystem, out ReadOnlySpan subPath) + .ThrowIfFailure(); + + fileSystem.DeleteDirectoryRecursively(subPath.ToString()); } public void CleanDirectoryRecursively(string path) { - throw new NotImplementedException(); + FindFileSystem(path.AsSpan(), out FileSystemAccessor fileSystem, out ReadOnlySpan subPath) + .ThrowIfFailure(); + + fileSystem.CleanDirectoryRecursively(subPath.ToString()); } public void DeleteFile(string path) { - throw new NotImplementedException(); + FindFileSystem(path.AsSpan(), out FileSystemAccessor fileSystem, out ReadOnlySpan subPath) + .ThrowIfFailure(); + + fileSystem.DeleteFile(subPath.ToString()); } public void RenameDirectory(string oldPath, string newPath) { - throw new NotImplementedException(); + FindFileSystem(oldPath.AsSpan(), out FileSystemAccessor oldFileSystem, out ReadOnlySpan oldSubPath) + .ThrowIfFailure(); + + FindFileSystem(newPath.AsSpan(), out FileSystemAccessor newFileSystem, out ReadOnlySpan newSubPath) + .ThrowIfFailure(); + + if (oldFileSystem != newFileSystem) + { + ThrowHelper.ThrowResult(ResultFsDifferentDestFileSystem); + } + + oldFileSystem.RenameDirectory(oldSubPath.ToString(), newSubPath.ToString()); } public void RenameFile(string oldPath, string newPath) { - throw new NotImplementedException(); + FindFileSystem(oldPath.AsSpan(), out FileSystemAccessor oldFileSystem, out ReadOnlySpan oldSubPath) + .ThrowIfFailure(); + + FindFileSystem(newPath.AsSpan(), out FileSystemAccessor newFileSystem, out ReadOnlySpan newSubPath) + .ThrowIfFailure(); + + if (oldFileSystem != newFileSystem) + { + ThrowHelper.ThrowResult(ResultFsDifferentDestFileSystem); + } + + oldFileSystem.RenameFile(oldSubPath.ToString(), newSubPath.ToString()); } - // How to report when entry isn't found? public DirectoryEntryType GetEntryType(string path) { - throw new NotImplementedException(); + FindFileSystem(path.AsSpan(), out FileSystemAccessor fileSystem, out ReadOnlySpan subPath) + .ThrowIfFailure(); + + return fileSystem.GetEntryType(subPath.ToString()); } public FileHandle OpenFile(string path, OpenMode mode) @@ -98,6 +138,37 @@ namespace LibHac.Fs return new DirectoryHandle(dir); } + long GetFreeSpaceSize(string path) + { + FindFileSystem(path.AsSpan(), out FileSystemAccessor fileSystem, out ReadOnlySpan subPath) + .ThrowIfFailure(); + + return fileSystem.GetFreeSpaceSize(subPath.ToString()); + } + + long GetTotalSpaceSize(string path) + { + FindFileSystem(path.AsSpan(), out FileSystemAccessor fileSystem, out ReadOnlySpan subPath) + .ThrowIfFailure(); + + return fileSystem.GetTotalSpaceSize(subPath.ToString()); + } + + FileTimeStampRaw GetFileTimeStamp(string path) + { + FindFileSystem(path.AsSpan(), out FileSystemAccessor fileSystem, out ReadOnlySpan subPath) + .ThrowIfFailure(); + + return fileSystem.GetFileTimeStampRaw(subPath.ToString()); + } + + public void Commit(string mountName) + { + MountTable.Find(mountName, out FileSystemAccessor fileSystem).ThrowIfFailure(); + + fileSystem.Commit(); + } + // ========================== // Operations on file handles // ========================== @@ -146,6 +217,19 @@ namespace LibHac.Fs handle.File.Dispose(); } + // ========================== + // Operations on directory handles + // ========================== + public int GetDirectoryEntryCount(DirectoryHandle handle) + { + return handle.Directory.GetEntryCount(); + } + + public IEnumerable ReadDirectory(DirectoryHandle handle) + { + return handle.Directory.Read(); + } + internal Result FindFileSystem(ReadOnlySpan path, out FileSystemAccessor fileSystem, out ReadOnlySpan subPath) { fileSystem = default; diff --git a/src/LibHac/Fs/ResultsFs.cs b/src/LibHac/Fs/ResultsFs.cs index 0b18cfd7..1d601739 100644 --- a/src/LibHac/Fs/ResultsFs.cs +++ b/src/LibHac/Fs/ResultsFs.cs @@ -4,7 +4,10 @@ { public const int ModuleFs = 2; + public static Result ResultFsPathNotFound => new Result(ModuleFs, 1); public static Result ResultFsMountNameAlreadyExists => new Result(ModuleFs, 60); + public static Result ResultFsDifferentDestFileSystem => new Result(ModuleFs, 6034); + public static Result ResultFsNullArgument => new Result(ModuleFs, 6063); public static Result ResultFsInvalidMountName => new Result(ModuleFs, 6065); public static Result ResultFsWriteStateUnflushed => new Result(ModuleFs, 6454); public static Result ResultFsWritableFileOpen => new Result(ModuleFs, 6457);