diff --git a/src/LibHac/IO/FileBase.cs b/src/LibHac/IO/FileBase.cs new file mode 100644 index 00000000..a2872aa3 --- /dev/null +++ b/src/LibHac/IO/FileBase.cs @@ -0,0 +1,23 @@ +using System; + +namespace LibHac.IO +{ + public abstract class FileBase : IFile + { + public abstract int Read(Span destination, long offset); + public abstract void Write(ReadOnlySpan source, long offset); + public abstract void Flush(); + public abstract long GetSize(); + public abstract long SetSize(); + + protected int GetAvailableSizeAndValidate(ReadOnlySpan span, long offset) + { + long fileLength = GetSize(); + + if (span == null) throw new ArgumentNullException(nameof(span)); + if (offset < 0) throw new ArgumentOutOfRangeException(nameof(offset), "Argument must be non-negative."); + + return (int)Math.Min(fileLength - offset, span.Length); + } + } +} diff --git a/src/LibHac/IO/IFile.cs b/src/LibHac/IO/IFile.cs index 70b5212c..00f26f66 100644 --- a/src/LibHac/IO/IFile.cs +++ b/src/LibHac/IO/IFile.cs @@ -4,7 +4,7 @@ namespace LibHac.IO { public interface IFile { - void Read(Span destination, long offset); + int Read(Span destination, long offset); void Write(ReadOnlySpan source, long offset); void Flush(); long GetSize(); diff --git a/src/LibHac/IO/RomFsFile.cs b/src/LibHac/IO/RomFsFile.cs index f67b506b..9b41d4f3 100644 --- a/src/LibHac/IO/RomFsFile.cs +++ b/src/LibHac/IO/RomFsFile.cs @@ -2,7 +2,7 @@ namespace LibHac.IO { - public class RomFsFile : IFile + public class RomFsFile : FileBase { private IStorage BaseStorage { get; } private long Offset { get; } @@ -15,29 +15,32 @@ namespace LibHac.IO Size = size; } - public void Read(Span destination, long offset) + public override int Read(Span destination, long offset) { long storageOffset = Offset + offset; + int toRead = GetAvailableSizeAndValidate(destination, offset); - BaseStorage.Read(destination, storageOffset); + BaseStorage.Read(destination.Slice(0, toRead), storageOffset); + + return toRead; } - public void Write(ReadOnlySpan source, long offset) + public override void Write(ReadOnlySpan source, long offset) { throw new NotImplementedException(); } - public void Flush() + public override void Flush() { throw new NotImplementedException(); } - public long GetSize() + public override long GetSize() { return Size; } - public long SetSize() + public override long SetSize() { throw new NotSupportedException(); } diff --git a/src/LibHac/IO/Storage.cs b/src/LibHac/IO/Storage.cs index 6a8cf33b..0a7cfc7e 100644 --- a/src/LibHac/IO/Storage.cs +++ b/src/LibHac/IO/Storage.cs @@ -95,7 +95,7 @@ namespace LibHac.IO if (Length != -1) { - if (offset + count > Length) throw new ArgumentException(); + if (offset + count > Length) throw new ArgumentException("The given offset and count exceed the length of the Storage"); } } @@ -107,7 +107,7 @@ namespace LibHac.IO if (Length != -1) { - if (offset + destination.Length > Length) throw new ArgumentException("Storage"); + if (offset + destination.Length > Length) throw new ArgumentException("The given offset and count exceed the length of the Storage"); } } }