diff --git a/src/LibHac/Fs/FileSystemExtensions.cs b/src/LibHac/Fs/FileSystemExtensions.cs index c55b1498..5fca64dd 100644 --- a/src/LibHac/Fs/FileSystemExtensions.cs +++ b/src/LibHac/Fs/FileSystemExtensions.cs @@ -13,7 +13,7 @@ namespace LibHac.Fs { Result rc; - foreach (DirectoryEntryEx entry in sourceFs.EnumerateEntries()) + foreach (DirectoryEntryEx entry in sourceFs.EnumerateEntries(sourcePath, "*", SearchOptions.Default)) { string subSrcPath = PathTools.Normalize(PathTools.Combine(sourcePath, entry.Name)); string subDstPath = PathTools.Normalize(PathTools.Combine(destPath, entry.Name)); @@ -107,7 +107,7 @@ namespace LibHac.Fs } } - private static DirectoryEntryEx GetDirectoryEntryEx(ref DirectoryEntry entry, string parentPath) + internal static DirectoryEntryEx GetDirectoryEntryEx(ref DirectoryEntry entry, string parentPath) { string name = entry.Name.FromUtf8Z(); string path = PathTools.Combine(parentPath, name); diff --git a/src/LibHac/FsClient/FileSystemClient.Directory.cs b/src/LibHac/FsClient/FileSystemClient.Directory.cs index 4395e55d..61b9151d 100644 --- a/src/LibHac/FsClient/FileSystemClient.Directory.cs +++ b/src/LibHac/FsClient/FileSystemClient.Directory.cs @@ -1,5 +1,4 @@ using System; -using System.Collections.Generic; using LibHac.Fs; namespace LibHac.FsClient @@ -8,18 +7,17 @@ namespace LibHac.FsClient { public Result GetDirectoryEntryCount(out long count, DirectoryHandle handle) { - throw new NotImplementedException(); + return FsManager.GetDirectoryEntryCount(out count, handle); } - // todo: change to not use IEnumerable - public IEnumerable ReadDirectory(DirectoryHandle handle) + public Result ReadDirectory(out long entriesRead, Span entryBuffer, DirectoryHandle handle) { - throw new NotImplementedException(); + return FsManager.ReadDirectory(out entriesRead, entryBuffer, handle); } public void CloseDirectory(DirectoryHandle handle) { - throw new NotImplementedException(); + FsManager.CloseDirectory(handle); } } } diff --git a/src/LibHac/FsClient/FileSystemClient.File.cs b/src/LibHac/FsClient/FileSystemClient.File.cs index b4b13a0f..51a6b4dd 100644 --- a/src/LibHac/FsClient/FileSystemClient.File.cs +++ b/src/LibHac/FsClient/FileSystemClient.File.cs @@ -7,52 +7,52 @@ namespace LibHac.FsClient { public Result ReadFile(FileHandle handle, long offset, Span destination) { - throw new NotImplementedException(); + return FsManager.ReadFile(handle, offset, destination); } public Result ReadFile(FileHandle handle, long offset, Span destination, ReadOption options) { - throw new NotImplementedException(); + return FsManager.ReadFile(handle, offset, destination, options); } public Result ReadFile(out long bytesRead, FileHandle handle, long offset, Span destination) { - throw new NotImplementedException(); + return FsManager.ReadFile(out bytesRead, handle, offset, destination); } public Result ReadFile(out long bytesRead, FileHandle handle, long offset, Span destination, ReadOption options) { - throw new NotImplementedException(); + return FsManager.ReadFile(out bytesRead, handle, offset, destination, options); } - public Result WriteFile(FileHandle handle, long offset, ReadOnlySpan source, WriteOption options) + public Result WriteFile(FileHandle handle, long offset, ReadOnlySpan source, WriteOption options) { - throw new NotImplementedException(); + return FsManager.WriteFile(handle, source, offset, options); } public Result FlushFile(FileHandle handle) { - throw new NotImplementedException(); + return FsManager.FlushFile(handle); } - public Result GetFileSize(out long size, FileHandle handle) + public Result GetFileSize(out long fileSize, FileHandle handle) { - throw new NotImplementedException(); + return FsManager.GetFileSize(out fileSize, handle); } public Result SetFileSize(FileHandle handle, long size) { - throw new NotImplementedException(); + return FsManager.SetFileSize(handle, size); } public OpenMode GetFileOpenMode(FileHandle handle) { - throw new NotImplementedException(); + return FsManager.GetFileOpenMode(handle); } public void CloseFile(FileHandle handle) { - throw new NotImplementedException(); + FsManager.CloseFile(handle); } } } diff --git a/src/LibHac/FsClient/FileSystemClient.FileSystem.cs b/src/LibHac/FsClient/FileSystemClient.FileSystem.cs index ebd4ed12..a0f6bd2e 100644 --- a/src/LibHac/FsClient/FileSystemClient.FileSystem.cs +++ b/src/LibHac/FsClient/FileSystemClient.FileSystem.cs @@ -1,4 +1,3 @@ -using System; using LibHac.Fs; namespace LibHac.FsClient @@ -7,77 +6,77 @@ namespace LibHac.FsClient { public Result CreateDirectory(string path) { - throw new NotImplementedException(); + return FsManager.CreateDirectory(path); } public Result CreateFile(string path, long size) { - throw new NotImplementedException(); + return CreateFile(path, size, CreateFileOptions.None); } public Result CreateFile(string path, long size, CreateFileOptions options) { - throw new NotImplementedException(); + return FsManager.CreateFile(path, size, options); } public Result DeleteDirectory(string path) { - throw new NotImplementedException(); + return FsManager.DeleteDirectory(path); } public Result DeleteDirectoryRecursively(string path) { - throw new NotImplementedException(); + return FsManager.DeleteDirectoryRecursively(path); } public Result CleanDirectoryRecursively(string path) { - throw new NotImplementedException(); + return FsManager.CleanDirectoryRecursively(path); } public Result DeleteFile(string path) { - throw new NotImplementedException(); + return FsManager.DeleteFile(path); } public Result RenameDirectory(string oldPath, string newPath) { - throw new NotImplementedException(); + return FsManager.RenameDirectory(oldPath, newPath); } public Result RenameFile(string oldPath, string newPath) { - throw new NotImplementedException(); + return FsManager.RenameFile(oldPath, newPath); } public Result GetEntryType(out DirectoryEntryType type, string path) { - throw new NotImplementedException(); + return FsManager.GetEntryType(out type, path); } public Result OpenFile(out FileHandle handle, string path, OpenMode mode) { - throw new NotImplementedException(); + return FsManager.OpenFile(out handle, path, mode); } public Result OpenDirectory(out DirectoryHandle handle, string path, OpenDirectoryMode mode) { - throw new NotImplementedException(); + return FsManager.OpenDirectory(out handle, path, mode); } - public Result GetFreeSpaceSize(out long size, string path) + public Result GetFreeSpaceSize(out long freeSpace, string path) { - throw new NotImplementedException(); + return FsManager.GetFreeSpaceSize(out freeSpace, path); } - public Result GetTotalSpaceSize(out long size, string path) + public Result GetTotalSpaceSize(out long totalSpace, string path) { - throw new NotImplementedException(); + return FsManager.GetTotalSpaceSize(out totalSpace, path); } public Result Commit(string mountName) { - throw new NotImplementedException(); + return FsManager.Commit(mountName); } } } \ No newline at end of file diff --git a/src/LibHac/FsClient/FileSystemManager.cs b/src/LibHac/FsClient/FileSystemManager.cs index 87d442ce..eadb8415 100644 --- a/src/LibHac/FsClient/FileSystemManager.cs +++ b/src/LibHac/FsClient/FileSystemManager.cs @@ -1,5 +1,4 @@ using System; -using System.Collections.Generic; using System.Runtime.CompilerServices; using LibHac.Fs; using LibHac.FsClient.Accessors; @@ -386,12 +385,27 @@ namespace LibHac.FsClient // ========================== // Operations on file handles // ========================== - public Result ReadFile(out long bytesRead, FileHandle handle, Span destination, long offset) + public Result ReadFile(FileHandle handle, long offset, Span destination) { - return ReadFile(out bytesRead, handle, destination, offset, ReadOption.None); + return ReadFile(handle, offset, destination, ReadOption.None); } - public Result ReadFile(out long bytesRead, FileHandle handle, Span destination, long offset, ReadOption option) + public Result ReadFile(FileHandle handle, long offset, Span destination, ReadOption option) + { + Result rc = ReadFile(out long bytesRead, handle, offset, destination, option); + if (rc.IsFailure()) return rc; + + if (bytesRead == destination.Length) return Result.Success; + + return ResultFs.ValueOutOfRange.Log(); + } + + public Result ReadFile(out long bytesRead, FileHandle handle, long offset, Span destination) + { + return ReadFile(out bytesRead, handle, offset, destination, ReadOption.None); + } + + public Result ReadFile(out long bytesRead, FileHandle handle, long offset, Span destination, ReadOption option) { Result rc; @@ -512,22 +526,7 @@ namespace LibHac.FsClient return handle.Directory.GetEntryCount(out count); } - public IEnumerable ReadDirectory(DirectoryHandle handle) - { - if (IsEnabledAccessLog() && IsEnabledHandleAccessLog(handle)) - { - TimeSpan startTime = Time.GetCurrent(); - IEnumerable entries = handle.Directory.Read(); - TimeSpan endTime = Time.GetCurrent(); - - OutputAccessLog(Result.Success, startTime, endTime, handle, string.Empty); - return entries; - } - - return handle.Directory.Read(); - } - - public Result ReadDirectory2(out long entriesRead, Span entryBuffer, DirectoryHandle handle) + public Result ReadDirectory(out long entriesRead, Span entryBuffer, DirectoryHandle handle) { Result rc; diff --git a/src/LibHac/FsClient/FileSystemManagerUtils.cs b/src/LibHac/FsClient/FileSystemManagerUtils.cs index af9bf0a6..e1e23cdc 100644 --- a/src/LibHac/FsClient/FileSystemManagerUtils.cs +++ b/src/LibHac/FsClient/FileSystemManagerUtils.cs @@ -1,6 +1,7 @@ using System; using System.Buffers; using System.Collections.Generic; +using LibHac.Common; using LibHac.Fs; using LibHac.FsClient.Accessors; @@ -16,7 +17,7 @@ namespace LibHac.FsClient using (sourceHandle) { - foreach (DirectoryEntryEx entry in fs.ReadDirectory(sourceHandle)) + foreach (DirectoryEntryEx entry in fs.EnumerateEntries(sourcePath, "*", SearchOptions.Default)) { string subSrcPath = PathTools.Normalize(PathTools.Combine(sourcePath, entry.Name)); string subDstPath = PathTools.Normalize(PathTools.Combine(destPath, entry.Name)); @@ -72,7 +73,7 @@ namespace LibHac.FsClient int toRead = (int)Math.Min(fileSize - offset, bufferSize); Span buf = buffer.AsSpan(0, toRead); - rc = fs.ReadFile(out long _, sourceHandle, buf, offset); + rc = fs.ReadFile(out long _, sourceHandle, offset, buf); if (rc.IsFailure()) return rc; rc = fs.WriteFile(destHandle, buf, offset); @@ -110,12 +111,18 @@ namespace LibHac.FsClient bool ignoreCase = searchOptions.HasFlag(SearchOptions.CaseInsensitive); bool recurse = searchOptions.HasFlag(SearchOptions.RecurseSubdirectories); + DirectoryEntry dirEntry = default; fs.OpenDirectory(out DirectoryHandle sourceHandle, path, OpenDirectoryMode.All).ThrowIfFailure(); using (sourceHandle) { - foreach (DirectoryEntryEx entry in fs.ReadDirectory(sourceHandle)) + while (true) { + fs.ReadDirectory(out long entriesRead, SpanHelpers.AsSpan(ref dirEntry), sourceHandle); + if (entriesRead == 0) break; + + DirectoryEntryEx entry = FileSystemExtensions.GetDirectoryEntryEx(ref dirEntry, path); + if (PathTools.MatchesPattern(searchPattern, entry.Name, ignoreCase)) { yield return entry; @@ -123,9 +130,9 @@ namespace LibHac.FsClient if (entry.Type != DirectoryEntryType.Directory || !recurse) continue; - string subPath = PathTools.Normalize(PathTools.Combine(path, entry.Name)); - - IEnumerable subEntries = fs.EnumerateEntries(subPath, searchPattern, searchOptions); + IEnumerable subEntries = + fs.EnumerateEntries(PathTools.Combine(path, entry.Name), searchPattern, + searchOptions); foreach (DirectoryEntryEx subEntry in subEntries) { diff --git a/src/hactoolnet/FsUtils.cs b/src/hactoolnet/FsUtils.cs index 1614a723..9aa361ee 100644 --- a/src/hactoolnet/FsUtils.cs +++ b/src/hactoolnet/FsUtils.cs @@ -30,7 +30,7 @@ namespace hactoolnet using (sourceHandle) { - foreach (DirectoryEntryEx entry in fs.ReadDirectory(sourceHandle)) + foreach (DirectoryEntryEx entry in fs.EnumerateEntries(sourcePath, "*", SearchOptions.Default)) { string subSrcPath = PathTools.Normalize(PathTools.Combine(sourcePath, entry.Name)); string subDstPath = PathTools.Normalize(PathTools.Combine(destPath, entry.Name)); @@ -92,7 +92,7 @@ namespace hactoolnet int toRead = (int)Math.Min(fileSize - offset, bufferSize); Span buf = buffer.AsSpan(0, toRead); - rc = fs.ReadFile(out long _, sourceHandle, buf, offset); + rc = fs.ReadFile(out long _, sourceHandle, offset, buf); if (rc.IsFailure()) return rc; rc = fs.WriteFile(destHandle, buf, offset);