diff --git a/src/LibHac/Fs/FileBase.cs b/src/LibHac/Fs/FileBase.cs index ab48f665..c8126bd4 100644 --- a/src/LibHac/Fs/FileBase.cs +++ b/src/LibHac/Fs/FileBase.cs @@ -12,8 +12,14 @@ namespace LibHac.Fs protected abstract Result ReadImpl(out long bytesRead, long offset, Span destination, ReadOption options); protected abstract Result WriteImpl(long offset, ReadOnlySpan source, WriteOption options); protected abstract Result FlushImpl(); - protected abstract Result GetSizeImpl(out long size); protected abstract Result SetSizeImpl(long size); + protected abstract Result GetSizeImpl(out long size); + + protected virtual Result OperateRangeImpl(Span outBuffer, OperationId operationId, long offset, long size, + ReadOnlySpan inBuffer) + { + return ResultFs.NotImplemented.Log(); + } public Result Read(out long bytesRead, long offset, Span destination, ReadOption options) { @@ -53,6 +59,14 @@ namespace LibHac.Fs return FlushImpl(); } + public Result SetSize(long size) + { + if (IsDisposed) return ResultFs.PreconditionViolation.Log(); + if (size < 0) return ResultFs.ValueOutOfRange.Log(); + + return SetSizeImpl(size); + } + public Result GetSize(out long size) { if (IsDisposed) @@ -64,12 +78,12 @@ namespace LibHac.Fs return GetSizeImpl(out size); } - public Result SetSize(long size) + public Result OperateRange(Span outBuffer, OperationId operationId, long offset, long size, + ReadOnlySpan inBuffer) { if (IsDisposed) return ResultFs.PreconditionViolation.Log(); - if (size < 0) return ResultFs.ValueOutOfRange.Log(); - return SetSizeImpl(size); + return OperateRange(outBuffer, operationId, offset, size, inBuffer); } public void Dispose() diff --git a/src/LibHac/Fs/FileSystemBase.cs b/src/LibHac/Fs/FileSystemBase.cs index 3f6ec78f..889cad2e 100644 --- a/src/LibHac/Fs/FileSystemBase.cs +++ b/src/LibHac/Fs/FileSystemBase.cs @@ -22,6 +22,29 @@ namespace LibHac.Fs protected abstract Result GetEntryTypeImpl(out DirectoryEntryType entryType, string path); protected abstract Result CommitImpl(); + protected virtual Result GetFreeSpaceSizeImpl(out long freeSpace, string path) + { + freeSpace = default; + return ResultFs.NotImplemented.Log(); + } + + protected virtual Result GetTotalSpaceSizeImpl(out long totalSpace, string path) + { + totalSpace = default; + return ResultFs.NotImplemented.Log(); + } + + protected virtual Result GetFileTimeStampRawImpl(out FileTimeStampRaw timeStamp, string path) + { + timeStamp = default; + return ResultFs.NotImplemented.Log(); + } + + protected virtual Result QueryEntryImpl(Span outBuffer, ReadOnlySpan inBuffer, QueryId queryId, string path) + { + return ResultFs.NotImplemented.Log(); + } + public Result CreateDirectory(string path) { if (IsDisposed) return ResultFs.PreconditionViolation.Log(); @@ -169,28 +192,5 @@ namespace LibHac.Fs } protected virtual void Dispose(bool disposing) { } - - protected virtual Result GetFreeSpaceSizeImpl(out long freeSpace, string path) - { - freeSpace = default; - return ResultFs.NotImplemented.Log(); - } - - protected virtual Result GetTotalSpaceSizeImpl(out long totalSpace, string path) - { - totalSpace = default; - return ResultFs.NotImplemented.Log(); - } - - protected virtual Result GetFileTimeStampRawImpl(out FileTimeStampRaw timeStamp, string path) - { - timeStamp = default; - return ResultFs.NotImplemented.Log(); - } - - protected virtual Result QueryEntryImpl(Span outBuffer, ReadOnlySpan inBuffer, QueryId queryId, string path) - { - return ResultFs.NotImplemented.Log(); - } } } diff --git a/src/LibHac/Fs/FsEnums.cs b/src/LibHac/Fs/FsEnums.cs index 08758ff7..ba9485b6 100644 --- a/src/LibHac/Fs/FsEnums.cs +++ b/src/LibHac/Fs/FsEnums.cs @@ -119,4 +119,12 @@ namespace LibHac.Fs None = 0, Flush = 1 } + + public enum OperationId + { + Clear = 0, + ClearSignature = 1, + InvalidateCache = 2, + QueryRange = 3 + } } diff --git a/src/LibHac/Fs/IFile.cs b/src/LibHac/Fs/IFile.cs index 1c98e082..29746104 100644 --- a/src/LibHac/Fs/IFile.cs +++ b/src/LibHac/Fs/IFile.cs @@ -44,6 +44,13 @@ namespace LibHac.Fs /// Result Flush(); + /// + /// Sets the size of the file in bytes. + /// + /// The desired size of the file in bytes. + /// The of the requested operation. + Result SetSize(long size); + /// /// Gets the number of bytes in the file. /// @@ -52,10 +59,15 @@ namespace LibHac.Fs Result GetSize(out long size); /// - /// Sets the size of the file in bytes. + /// Performs various operations on the file. Used to extend the functionality of the interface. /// - /// The desired size of the file in bytes. + /// A buffer that will contain the response from the operation. + /// The operation to be performed. + /// The offset of the range to operate on. + /// The size of the range to operate on. + /// An input buffer. Size may vary depending on the operation performed. /// The of the requested operation. - Result SetSize(long size); + Result OperateRange(Span outBuffer, OperationId operationId, long offset, long size, + ReadOnlySpan inBuffer); } } \ No newline at end of file diff --git a/src/LibHac/Fs/IFileSystem.cs b/src/LibHac/Fs/IFileSystem.cs index 5e6275b6..91721465 100644 --- a/src/LibHac/Fs/IFileSystem.cs +++ b/src/LibHac/Fs/IFileSystem.cs @@ -8,20 +8,6 @@ namespace LibHac.Fs /// public interface IFileSystem { - /// - /// Creates all directories and subdirectories in the specified path unless they already exist. - /// - /// The full path of the directory to create. - /// The of the requested operation. - /// - /// The following codes may be returned under certain conditions: - /// - /// The parent directory of the specified path does not exist: - /// Specified path already exists as either a file or directory: - /// Insufficient free space to create the directory: - /// - Result CreateDirectory(string path); - /// /// Creates or overwrites a file at the specified path. /// @@ -39,6 +25,32 @@ namespace LibHac.Fs /// Result CreateFile(string path, long size, CreateFileOptions options); + /// + /// Deletes the specified file. + /// + /// The full path of the file to delete. + /// The of the requested operation. + /// + /// The following codes may be returned under certain conditions: + /// + /// The specified path does not exist or is a directory: + /// + Result DeleteFile(string path); + + /// + /// Creates all directories and subdirectories in the specified path unless they already exist. + /// + /// The full path of the directory to create. + /// The of the requested operation. + /// + /// The following codes may be returned under certain conditions: + /// + /// The parent directory of the specified path does not exist: + /// Specified path already exists as either a file or directory: + /// Insufficient free space to create the directory: + /// + Result CreateDirectory(string path); + /// /// Deletes the specified directory. /// @@ -77,46 +89,20 @@ namespace LibHac.Fs Result CleanDirectoryRecursively(string path); /// - /// Deletes the specified file. + /// Renames or moves a file to a new location. /// - /// The full path of the file to delete. + /// The full path of the file to rename. + /// The new full path of the file. /// The of the requested operation. /// + /// If and are the same, this function does nothing and returns successfully. /// The following codes may be returned under certain conditions: /// - /// The specified path does not exist or is a directory: + /// does not exist or is a directory: + /// 's parent directory does not exist: + /// already exists as either a file or directory: /// - Result DeleteFile(string path); - - /// - /// Creates an instance for enumerating the specified directory. - /// - /// If the operation returns successfully, - /// An instance for the specified directory. - /// The directory's full path. - /// Specifies which sub-entries should be enumerated. - /// The of the requested operation. - /// - /// The following codes may be returned under certain conditions: - /// - /// The specified path does not exist or is a file: - /// - Result OpenDirectory(out IDirectory directory, string path, OpenDirectoryMode mode); - - /// - /// Opens an instance for the specified path. - /// - /// If the operation returns successfully, - /// An instance for the specified path. - /// The full path of the file to open. - /// Specifies the access permissions of the created . - /// The of the requested operation. - /// - /// The following codes may be returned under certain conditions: - /// - /// The specified path does not exist or is a directory: - /// - Result OpenFile(out IFile file, string path, OpenMode mode); + Result RenameFile(string oldPath, string newPath); /// /// Renames or moves a directory to a new location. @@ -135,22 +121,6 @@ namespace LibHac.Fs /// Result RenameDirectory(string oldPath, string newPath); - /// - /// Renames or moves a file to a new location. - /// - /// The full path of the file to rename. - /// The new full path of the file. - /// The of the requested operation. - /// - /// If and are the same, this function does nothing and returns successfully. - /// The following codes may be returned under certain conditions: - /// - /// does not exist or is a directory: - /// 's parent directory does not exist: - /// already exists as either a file or directory: - /// - Result RenameFile(string oldPath, string newPath); - /// /// Determines whether the specified path is a file or directory, or does not exist. /// @@ -180,6 +150,43 @@ namespace LibHac.Fs /// The of the requested operation. Result GetTotalSpaceSize(out long totalSpace, string path); + /// + /// Opens an instance for the specified path. + /// + /// If the operation returns successfully, + /// An instance for the specified path. + /// The full path of the file to open. + /// Specifies the access permissions of the created . + /// The of the requested operation. + /// + /// The following codes may be returned under certain conditions: + /// + /// The specified path does not exist or is a directory: + /// + Result OpenFile(out IFile file, string path, OpenMode mode); + + /// + /// Creates an instance for enumerating the specified directory. + /// + /// If the operation returns successfully, + /// An instance for the specified directory. + /// The directory's full path. + /// Specifies which sub-entries should be enumerated. + /// The of the requested operation. + /// + /// The following codes may be returned under certain conditions: + /// + /// The specified path does not exist or is a file: + /// + Result OpenDirectory(out IDirectory directory, string path, OpenDirectoryMode mode); + + /// + /// Commits any changes to a transactional file system. + /// Does nothing if called on a non-transactional file system. + /// + /// The of the requested operation. + Result Commit(); + /// /// Gets the creation, last accessed, and last modified timestamps of a file or directory. /// @@ -194,13 +201,6 @@ namespace LibHac.Fs /// Result GetFileTimeStampRaw(out FileTimeStampRaw timeStamp, string path); - /// - /// Commits any changes to a transactional file system. - /// Does nothing if called on a non-transactional file system. - /// - /// The of the requested operation. - Result Commit(); - /// /// Performs a query on the specified file. /// diff --git a/src/LibHac/Fs/IStorage.cs b/src/LibHac/Fs/IStorage.cs index 8f0a1b47..455388ef 100644 --- a/src/LibHac/Fs/IStorage.cs +++ b/src/LibHac/Fs/IStorage.cs @@ -42,5 +42,17 @@ namespace LibHac.Fs /// /// The size of the in bytes. Result GetSize(out long size); + + /// + /// Performs various operations on the file. Used to extend the functionality of the interface. + /// + /// A buffer that will contain the response from the operation. + /// The operation to be performed. + /// The offset of the range to operate on. + /// The size of the range to operate on. + /// An input buffer. Size may vary depending on the operation performed. + /// The of the requested operation. + Result OperateRange(Span outBuffer, OperationId operationId, long offset, long size, + ReadOnlySpan inBuffer); } } diff --git a/src/LibHac/Fs/StorageBase.cs b/src/LibHac/Fs/StorageBase.cs index 33044952..f764494f 100644 --- a/src/LibHac/Fs/StorageBase.cs +++ b/src/LibHac/Fs/StorageBase.cs @@ -15,6 +15,12 @@ namespace LibHac.Fs protected abstract Result GetSizeImpl(out long size); protected abstract Result SetSizeImpl(long size); + protected virtual Result OperateRangeImpl(Span outBuffer, OperationId operationId, long offset, long size, + ReadOnlySpan inBuffer) + { + return ResultFs.NotImplemented.Log(); + } + public Result Read(long offset, Span destination) { if (IsDisposed) return ResultFs.PreconditionViolation.Log(); @@ -51,6 +57,14 @@ namespace LibHac.Fs return GetSizeImpl(out size); } + public Result OperateRange(Span outBuffer, OperationId operationId, long offset, long size, + ReadOnlySpan inBuffer) + { + if (IsDisposed) return ResultFs.PreconditionViolation.Log(); + + return OperateRange(outBuffer, operationId, offset, size, inBuffer); + } + public void Dispose() { // Make sure Dispose is only called once