diff --git a/build/CodeGen/results.csv b/build/CodeGen/results.csv index 85ef30d2..38f49070 100644 --- a/build/CodeGen/results.csv +++ b/build/CodeGen/results.csv @@ -168,6 +168,8 @@ Module,DescriptionStart,DescriptionEnd,Name,Summary 2,6069,,InvalidCacheStorageSize, 2,6070,,InvalidCacheStorageIndex, 2,6071,,InvalidCommitNameCount,Up to 10 file systems can be committed at the same time. +2,6072,,InvalidOpenMode, +2,6074,,InvalidDirectoryOpenMode, 2,6080,6099,InvalidEnumValue, 2,6081,,InvalidSaveDataState, diff --git a/src/LibHac/Fs/Fsa/IDirectory2.cs b/src/LibHac/Fs/Fsa/IDirectory2.cs new file mode 100644 index 00000000..064279df --- /dev/null +++ b/src/LibHac/Fs/Fsa/IDirectory2.cs @@ -0,0 +1,35 @@ +using System; + +namespace LibHac.Fs.Fsa +{ + // ReSharper disable once InconsistentNaming + public abstract class IDirectory2 : IDisposable + { + public Result Read(out long entriesRead, Span entryBuffer) + { + if (entryBuffer.IsEmpty) + { + entriesRead = 0; + return Result.Success; + } + + return DoRead(out entriesRead, entryBuffer); + } + + public Result GetEntryCount(out long entryCount) + { + return DoGetEntryCount(out entryCount); + } + + protected abstract Result DoRead(out long entriesRead, Span entryBuffer); + protected abstract Result DoGetEntryCount(out long entryCount); + + protected virtual void Dispose(bool disposing) { } + + public void Dispose() + { + Dispose(true); + GC.SuppressFinalize(this); + } + } +} diff --git a/src/LibHac/Fs/Fsa/IFileSystem2.cs b/src/LibHac/Fs/Fsa/IFileSystem2.cs new file mode 100644 index 00000000..2d1ff525 --- /dev/null +++ b/src/LibHac/Fs/Fsa/IFileSystem2.cs @@ -0,0 +1,235 @@ +using System; +using LibHac.Common; + +namespace LibHac.Fs.Fsa +{ + // ReSharper disable once InconsistentNaming + public abstract class IFileSystem2 : IDisposable + { + public Result CreateFile(U8Span path, long size, CreateFileOptions option) + { + if (path.IsNull()) + return ResultFs.NullptrArgument.Log(); + + if (size < 0) + return ResultFs.OutOfRange.Log(); + + return DoCreateFile(path, size, option); + } + + public Result DeleteFile(U8Span path) + { + if (path.IsNull()) + return ResultFs.NullptrArgument.Log(); + + return DoDeleteFile(path); + } + + public Result CreateDirectory(U8Span path) + { + if (path.IsNull()) + return ResultFs.NullptrArgument.Log(); + + return DoCreateDirectory(path); + } + + public Result DeleteDirectory(U8Span path) + { + if (path.IsNull()) + return ResultFs.NullptrArgument.Log(); + + return DoDeleteDirectory(path); + } + + public Result DeleteDirectoryRecursively(U8Span path) + { + if (path.IsNull()) + return ResultFs.NullptrArgument.Log(); + + return DoDeleteDirectoryRecursively(path); + } + + public Result CleanDirectoryRecursively(U8Span path) + { + if (path.IsNull()) + return ResultFs.NullptrArgument.Log(); + + return DoCleanDirectoryRecursively(path); + } + + public Result RenameFile(U8Span oldPath, U8Span newPath) + { + if (oldPath.IsNull()) + return ResultFs.NullptrArgument.Log(); + + if (newPath.IsNull()) + return ResultFs.NullptrArgument.Log(); + + return DoRenameFile(oldPath, newPath); + } + + public Result RenameDirectory(U8Span oldPath, U8Span newPath) + { + if (oldPath.IsNull()) + return ResultFs.NullptrArgument.Log(); + + if (newPath.IsNull()) + return ResultFs.NullptrArgument.Log(); + + return DoRenameDirectory(oldPath, newPath); + } + + public Result GetEntryType(out DirectoryEntryType entryType, U8Span path) + { + if (path.IsNull()) + { + entryType = default; + return ResultFs.NullptrArgument.Log(); + } + + return DoGetEntryType(out entryType, path); + } + + public Result GetFreeSpaceSize(out long freeSpace, U8Span path) + { + if (path.IsNull()) + { + freeSpace = default; + return ResultFs.NullptrArgument.Log(); + } + + return DoGetFreeSpaceSize(out freeSpace, path); + } + + public Result GetTotalSpaceSize(out long totalSpace, U8Span path) + { + if (path.IsNull()) + { + totalSpace = default; + return ResultFs.NullptrArgument.Log(); + } + + return DoGetTotalSpaceSize(out totalSpace, path); + } + + public Result OpenFile(out IFile2 file, U8Span path, OpenMode mode) + { + if (path.IsNull()) + { + file = default; + return ResultFs.NullptrArgument.Log(); + } + + if ((mode & OpenMode.ReadWrite) == 0) + { + file = default; + return ResultFs.InvalidOpenMode.Log(); + } + + if ((mode & ~OpenMode.All) != 0) + { + file = default; + return ResultFs.InvalidOpenMode.Log(); + } + + return DoOpenFile(out file, path, mode); + } + + public Result OpenDirectory(out IDirectory2 directory, U8Span path, OpenDirectoryMode mode) + { + if (path.IsNull()) + { + directory = default; + return ResultFs.NullptrArgument.Log(); + } + + if ((mode & OpenDirectoryMode.All) == 0) + { + directory = default; + return ResultFs.InvalidOpenMode.Log(); + } + + if ((mode & ~(OpenDirectoryMode.All | OpenDirectoryMode.NoFileSize)) != 0) + { + directory = default; + return ResultFs.InvalidOpenMode.Log(); + } + + return DoOpenDirectory(out directory, path, mode); + } + + public Result Commit() => DoCommit(); + + public Result CommitProvisionally(long counter) => DoCommitProvisionally(counter); + + public Result Rollback() => DoRollback(); + + public Result Flush() => DoFlush(); + + public Result GetFileTimeStampRaw(out FileTimeStampRaw timeStamp, U8Span path) + { + if (path.IsNull()) + { + timeStamp = default; + return ResultFs.NullptrArgument.Log(); + } + + return DoGetFileTimeStampRaw(out timeStamp, path); + } + + public Result QueryEntry(Span outBuffer, ReadOnlySpan inBuffer, QueryId queryId, U8Span path) + { + if (path.IsNull()) + return ResultFs.NullptrArgument.Log(); + + return DoQueryEntry(outBuffer, inBuffer, queryId, path); + } + + protected abstract Result DoCreateFile(U8Span path, long size, CreateFileOptions option); + protected abstract Result DoDeleteFile(U8Span path); + protected abstract Result DoCreateDirectory(U8Span path); + protected abstract Result DoDeleteDirectory(U8Span path); + protected abstract Result DoDeleteDirectoryRecursively(U8Span path); + protected abstract Result DoCleanDirectoryRecursively(U8Span path); + protected abstract Result DoRenameFile(U8Span oldPath, U8Span newPath); + protected abstract Result DoRenameDirectory(U8Span oldPath, U8Span newPath); + protected abstract Result DoGetEntryType(out DirectoryEntryType entryType, U8Span path); + + protected virtual Result DoGetFreeSpaceSize(out long freeSpace, U8Span path) + { + freeSpace = default; + return ResultFs.NotImplemented.Log(); + } + + protected virtual Result DoGetTotalSpaceSize(out long totalSpace, U8Span path) + { + totalSpace = default; + return ResultFs.NotImplemented.Log(); + } + + protected abstract Result DoOpenFile(out IFile2 file, U8Span path, OpenMode mode); + protected abstract Result DoOpenDirectory(out IDirectory2 directory, U8Span path, OpenDirectoryMode mode); + protected abstract Result DoCommit(); + + protected virtual Result DoCommitProvisionally(long counter) => ResultFs.NotImplemented.Log(); + protected virtual Result DoRollback() => ResultFs.NotImplemented.Log(); + protected virtual Result DoFlush() => ResultFs.NotImplemented.Log(); + + protected virtual Result DoGetFileTimeStampRaw(out FileTimeStampRaw timeStamp, U8Span path) + { + timeStamp = default; + return ResultFs.NotImplemented.Log(); + } + + protected virtual Result DoQueryEntry(Span outBuffer, ReadOnlySpan inBuffer, QueryId queryId, + U8Span path) => ResultFs.NotImplemented.Log(); + + protected virtual void Dispose(bool disposing) { } + + public void Dispose() + { + Dispose(true); + GC.SuppressFinalize(this); + } + } +} diff --git a/src/LibHac/Fs/ResultFs.cs b/src/LibHac/Fs/ResultFs.cs index 00d083b4..d9c06d7d 100644 --- a/src/LibHac/Fs/ResultFs.cs +++ b/src/LibHac/Fs/ResultFs.cs @@ -329,6 +329,10 @@ namespace LibHac.Fs public static Result.Base InvalidCacheStorageIndex => new Result.Base(ModuleFs, 6070); /// Up to 10 file systems can be committed at the same time.
Error code: 2002-6071; Inner value: 0x2f6e02
public static Result.Base InvalidCommitNameCount => new Result.Base(ModuleFs, 6071); + /// Error code: 2002-6072; Inner value: 0x2f7002 + public static Result.Base InvalidOpenMode => new Result.Base(ModuleFs, 6072); + /// Error code: 2002-6074; Inner value: 0x2f7402 + public static Result.Base InvalidDirectoryOpenMode => new Result.Base(ModuleFs, 6074); /// Error code: 2002-6080; Range: 6080-6099; Inner value: 0x2f8002 public static Result.Base InvalidEnumValue { [MethodImpl(MethodImplOptions.AggressiveInlining)] get => new Result.Base(ModuleFs, 6080, 6099); }