From 775478fa163e981c3732ba5bd2a19a2d0bbd1834 Mon Sep 17 00:00:00 2001 From: Alex Barney Date: Tue, 4 Jun 2019 23:32:19 -0500 Subject: [PATCH] Add read and write options to IFile interface --- src/LibHac/Fs/AesXtsFile.cs | 9 +++++++-- src/LibHac/Fs/AesXtsFileSystem.cs | 2 +- src/LibHac/Fs/ConcatenationFile.cs | 13 +++++++++---- src/LibHac/Fs/DirectorySaveDataFile.cs | 8 ++++---- src/LibHac/Fs/FileBase.cs | 17 +++++++++++++++-- src/LibHac/Fs/FileSystemExtensions.cs | 10 ++++++++++ src/LibHac/Fs/IFile.cs | 6 ++++-- src/LibHac/Fs/LocalFile.cs | 8 ++++---- src/LibHac/Fs/NullFile.cs | 4 ++-- src/LibHac/Fs/PartitionFile.cs | 4 ++-- src/LibHac/Fs/ReadOnlyFile.cs | 6 +++--- src/LibHac/Fs/RomFs/RomFsFile.cs | 4 ++-- src/LibHac/Fs/Save/SaveDataFile.cs | 9 +++++++-- src/LibHac/Fs/StorageFile.cs | 11 ++++++++--- src/LibHac/Fs/StreamFile.cs | 9 +++++++-- 15 files changed, 85 insertions(+), 35 deletions(-) diff --git a/src/LibHac/Fs/AesXtsFile.cs b/src/LibHac/Fs/AesXtsFile.cs index 62f772b0..b0e6ef6c 100644 --- a/src/LibHac/Fs/AesXtsFile.cs +++ b/src/LibHac/Fs/AesXtsFile.cs @@ -44,7 +44,7 @@ namespace LibHac.Fs return key; } - public override int Read(Span destination, long offset) + public override int Read(Span destination, long offset, ReadOption options) { int toRead = ValidateReadParamsAndGetSize(destination, offset); @@ -53,11 +53,16 @@ namespace LibHac.Fs return toRead; } - public override void Write(ReadOnlySpan source, long offset) + public override void Write(ReadOnlySpan source, long offset, WriteOption options) { ValidateWriteParams(source, offset); BaseStorage.Write(source, offset); + + if ((options & WriteOption.Flush) != 0) + { + Flush(); + } } public override void Flush() diff --git a/src/LibHac/Fs/AesXtsFileSystem.cs b/src/LibHac/Fs/AesXtsFileSystem.cs index 6b669931..e7241980 100644 --- a/src/LibHac/Fs/AesXtsFileSystem.cs +++ b/src/LibHac/Fs/AesXtsFileSystem.cs @@ -246,7 +246,7 @@ namespace LibHac.Fs using (IFile file = BaseFileSystem.OpenFile(filePath, OpenMode.ReadWrite)) { - file.Write(header.ToBytes(false), 0); + file.Write(header.ToBytes(false), 0, WriteOption.Flush); } } } diff --git a/src/LibHac/Fs/ConcatenationFile.cs b/src/LibHac/Fs/ConcatenationFile.cs index 5d8343f6..ad738465 100644 --- a/src/LibHac/Fs/ConcatenationFile.cs +++ b/src/LibHac/Fs/ConcatenationFile.cs @@ -31,7 +31,7 @@ namespace LibHac.Fs ToDispose.AddRange(Sources); } - public override int Read(Span destination, long offset) + public override int Read(Span destination, long offset, ReadOption options) { long inPos = offset; int outPos = 0; @@ -45,7 +45,7 @@ namespace LibHac.Fs long fileEndOffset = Math.Min((fileIndex + 1) * SubFileSize, GetSize()); int bytesToRead = (int)Math.Min(fileEndOffset - inPos, remaining); - int bytesRead = file.Read(destination.Slice(outPos, bytesToRead), fileOffset); + int bytesRead = file.Read(destination.Slice(outPos, bytesToRead), fileOffset, options); outPos += bytesRead; inPos += bytesRead; @@ -57,7 +57,7 @@ namespace LibHac.Fs return outPos; } - public override void Write(ReadOnlySpan source, long offset) + public override void Write(ReadOnlySpan source, long offset, WriteOption options) { ValidateWriteParams(source, offset); @@ -73,12 +73,17 @@ namespace LibHac.Fs long fileEndOffset = Math.Min((fileIndex + 1) * SubFileSize, GetSize()); int bytesToWrite = (int)Math.Min(fileEndOffset - outPos, remaining); - file.Write(source.Slice(inPos, bytesToWrite), fileOffset); + file.Write(source.Slice(inPos, bytesToWrite), fileOffset, options); outPos += bytesToWrite; inPos += bytesToWrite; remaining -= bytesToWrite; } + + if ((options & WriteOption.Flush) != 0) + { + Flush(); + } } public override void Flush() diff --git a/src/LibHac/Fs/DirectorySaveDataFile.cs b/src/LibHac/Fs/DirectorySaveDataFile.cs index 5cebc989..7bda0da9 100644 --- a/src/LibHac/Fs/DirectorySaveDataFile.cs +++ b/src/LibHac/Fs/DirectorySaveDataFile.cs @@ -16,14 +16,14 @@ namespace LibHac.Fs ToDispose.Add(BaseFile); } - public override int Read(Span destination, long offset) + public override int Read(Span destination, long offset, ReadOption options) { - return BaseFile.Read(destination, offset); + return BaseFile.Read(destination, offset, options); } - public override void Write(ReadOnlySpan source, long offset) + public override void Write(ReadOnlySpan source, long offset, WriteOption options) { - BaseFile.Write(source, offset); + BaseFile.Write(source, offset, options); } public override void Flush() diff --git a/src/LibHac/Fs/FileBase.cs b/src/LibHac/Fs/FileBase.cs index f63b2f93..10962d40 100644 --- a/src/LibHac/Fs/FileBase.cs +++ b/src/LibHac/Fs/FileBase.cs @@ -8,8 +8,8 @@ namespace LibHac.Fs protected bool IsDisposed { get; private set; } internal List ToDispose { get; } = new List(); - public abstract int Read(Span destination, long offset); - public abstract void Write(ReadOnlySpan source, long offset); + public abstract int Read(Span destination, long offset, ReadOption options); + public abstract void Write(ReadOnlySpan source, long offset, WriteOption options); public abstract void Flush(); public abstract long GetSize(); public abstract void SetSize(long size); @@ -90,4 +90,17 @@ namespace LibHac.Fs Append = 4, ReadWrite = Read | Write } + + [Flags] + public enum ReadOption + { + None = 0 + } + + [Flags] + public enum WriteOption + { + None = 0, + Flush = 1 + } } diff --git a/src/LibHac/Fs/FileSystemExtensions.cs b/src/LibHac/Fs/FileSystemExtensions.cs index 1a5ac0be..a6455648 100644 --- a/src/LibHac/Fs/FileSystemExtensions.cs +++ b/src/LibHac/Fs/FileSystemExtensions.cs @@ -204,6 +204,16 @@ namespace LibHac.Fs } } } + + public static int Read(this IFile file, Span destination, long offset) + { + return file.Read(destination, offset, ReadOption.None); + } + + public static void Write(this IFile file, ReadOnlySpan source, long offset) + { + file.Write(source, offset, WriteOption.None); + } } [Flags] diff --git a/src/LibHac/Fs/IFile.cs b/src/LibHac/Fs/IFile.cs index d3d34848..22bef0bf 100644 --- a/src/LibHac/Fs/IFile.cs +++ b/src/LibHac/Fs/IFile.cs @@ -29,20 +29,22 @@ namespace LibHac.Fs /// The buffer where the read bytes will be stored. /// The number of bytes read will be no larger than the length of the buffer. /// The offset in the at which to begin reading. + /// Options for reading from the . /// The total number of bytes read into the buffer. This can be less than the /// size of the buffer if the IFile is too short to fulfill the request. /// is invalid. /// The file's does not allow reading. - int Read(Span destination, long offset); + int Read(Span destination, long offset, ReadOption options); /// /// Writes a sequence of bytes to the current . /// /// The buffer containing the bytes to be written. /// The offset in the at which to begin writing. + /// Options for writing to the . /// is negative. /// The file's does not allow this request. - void Write(ReadOnlySpan source, long offset); + void Write(ReadOnlySpan source, long offset, WriteOption options); /// /// Causes any buffered data to be written to the underlying device. diff --git a/src/LibHac/Fs/LocalFile.cs b/src/LibHac/Fs/LocalFile.cs index 43c215fc..1c3859cc 100644 --- a/src/LibHac/Fs/LocalFile.cs +++ b/src/LibHac/Fs/LocalFile.cs @@ -20,20 +20,20 @@ namespace LibHac.Fs ToDispose.Add(Stream); } - public override int Read(Span destination, long offset) + public override int Read(Span destination, long offset, ReadOption options) { int toRead = ValidateReadParamsAndGetSize(destination, offset); - File.Read(destination.Slice(0, toRead), offset); + File.Read(destination.Slice(0, toRead), offset, options); return toRead; } - public override void Write(ReadOnlySpan source, long offset) + public override void Write(ReadOnlySpan source, long offset, WriteOption options) { ValidateWriteParams(source, offset); - File.Write(source, offset); + File.Write(source, offset, options); } public override void Flush() diff --git a/src/LibHac/Fs/NullFile.cs b/src/LibHac/Fs/NullFile.cs index f45d9f3f..71081c69 100644 --- a/src/LibHac/Fs/NullFile.cs +++ b/src/LibHac/Fs/NullFile.cs @@ -13,14 +13,14 @@ namespace LibHac.Fs private long Length { get; } - public override int Read(Span destination, long offset) + public override int Read(Span destination, long offset, ReadOption options) { int toRead = ValidateReadParamsAndGetSize(destination, offset); destination.Slice(0, toRead).Clear(); return toRead; } - public override void Write(ReadOnlySpan source, long offset) + public override void Write(ReadOnlySpan source, long offset, WriteOption options) { } diff --git a/src/LibHac/Fs/PartitionFile.cs b/src/LibHac/Fs/PartitionFile.cs index a84bf375..8df0901f 100644 --- a/src/LibHac/Fs/PartitionFile.cs +++ b/src/LibHac/Fs/PartitionFile.cs @@ -16,7 +16,7 @@ namespace LibHac.Fs Size = size; } - public override int Read(Span destination, long offset) + public override int Read(Span destination, long offset, ReadOption options) { int toRead = ValidateReadParamsAndGetSize(destination, offset); @@ -26,7 +26,7 @@ namespace LibHac.Fs return toRead; } - public override void Write(ReadOnlySpan source, long offset) + public override void Write(ReadOnlySpan source, long offset, WriteOption options) { throw new NotImplementedException(); } diff --git a/src/LibHac/Fs/ReadOnlyFile.cs b/src/LibHac/Fs/ReadOnlyFile.cs index 39fa0f5c..be45b881 100644 --- a/src/LibHac/Fs/ReadOnlyFile.cs +++ b/src/LibHac/Fs/ReadOnlyFile.cs @@ -11,9 +11,9 @@ namespace LibHac.Fs BaseFile = baseFile; } - public override int Read(Span destination, long offset) + public override int Read(Span destination, long offset, ReadOption options) { - return BaseFile.Read(destination, offset); + return BaseFile.Read(destination, offset, options); } public override long GetSize() @@ -22,7 +22,7 @@ namespace LibHac.Fs } public override void Flush() { } - public override void Write(ReadOnlySpan source, long offset) => throw new NotSupportedException(); + public override void Write(ReadOnlySpan source, long offset, WriteOption options) => throw new NotSupportedException(); public override void SetSize(long size) => throw new NotSupportedException(); } } diff --git a/src/LibHac/Fs/RomFs/RomFsFile.cs b/src/LibHac/Fs/RomFs/RomFsFile.cs index 419fe834..534dba6f 100644 --- a/src/LibHac/Fs/RomFs/RomFsFile.cs +++ b/src/LibHac/Fs/RomFs/RomFsFile.cs @@ -16,7 +16,7 @@ namespace LibHac.Fs.RomFs Size = size; } - public override int Read(Span destination, long offset) + public override int Read(Span destination, long offset, ReadOption options) { int toRead = ValidateReadParamsAndGetSize(destination, offset); @@ -26,7 +26,7 @@ namespace LibHac.Fs.RomFs return toRead; } - public override void Write(ReadOnlySpan source, long offset) + public override void Write(ReadOnlySpan source, long offset, WriteOption options) { throw new NotImplementedException(); } diff --git a/src/LibHac/Fs/Save/SaveDataFile.cs b/src/LibHac/Fs/Save/SaveDataFile.cs index 4dd23161..c6ba6bf1 100644 --- a/src/LibHac/Fs/Save/SaveDataFile.cs +++ b/src/LibHac/Fs/Save/SaveDataFile.cs @@ -19,7 +19,7 @@ namespace LibHac.Fs.Save Size = size; } - public override int Read(Span destination, long offset) + public override int Read(Span destination, long offset, ReadOption options) { int toRead = ValidateReadParamsAndGetSize(destination, offset); @@ -28,11 +28,16 @@ namespace LibHac.Fs.Save return toRead; } - public override void Write(ReadOnlySpan source, long offset) + public override void Write(ReadOnlySpan source, long offset, WriteOption options) { ValidateWriteParams(source, offset); BaseStorage.Write(source, offset); + + if ((options & WriteOption.Flush) != 0) + { + Flush(); + } } public override void Flush() diff --git a/src/LibHac/Fs/StorageFile.cs b/src/LibHac/Fs/StorageFile.cs index 8462e53a..ce362ebe 100644 --- a/src/LibHac/Fs/StorageFile.cs +++ b/src/LibHac/Fs/StorageFile.cs @@ -5,14 +5,14 @@ namespace LibHac.Fs public class StorageFile : FileBase { private IStorage BaseStorage { get; } - + public StorageFile(IStorage baseStorage, OpenMode mode) { BaseStorage = baseStorage; Mode = mode; } - public override int Read(Span destination, long offset) + public override int Read(Span destination, long offset, ReadOption options) { int toRead = ValidateReadParamsAndGetSize(destination, offset); @@ -21,11 +21,16 @@ namespace LibHac.Fs return toRead; } - public override void Write(ReadOnlySpan source, long offset) + public override void Write(ReadOnlySpan source, long offset, WriteOption options) { ValidateWriteParams(source, offset); BaseStorage.Write(source, offset); + + if ((options & WriteOption.Flush) != 0) + { + Flush(); + } } public override void Flush() diff --git a/src/LibHac/Fs/StreamFile.cs b/src/LibHac/Fs/StreamFile.cs index 42129f79..e81b642f 100644 --- a/src/LibHac/Fs/StreamFile.cs +++ b/src/LibHac/Fs/StreamFile.cs @@ -21,7 +21,7 @@ namespace LibHac.Fs Mode = mode; } - public override int Read(Span destination, long offset) + public override int Read(Span destination, long offset, ReadOption options) { #if STREAM_SPAN lock (Locker) @@ -56,7 +56,7 @@ namespace LibHac.Fs #endif } - public override void Write(ReadOnlySpan source, long offset) + public override void Write(ReadOnlySpan source, long offset, WriteOption options) { #if STREAM_SPAN lock (Locker) @@ -78,6 +78,11 @@ namespace LibHac.Fs } finally { ArrayPool.Shared.Return(buffer); } #endif + + if ((options & WriteOption.Flush) != 0) + { + Flush(); + } } public override void Flush()