From d7ae809cf34393f55fd3a64600cc4f15e0b6be65 Mon Sep 17 00:00:00 2001 From: Alex Barney Date: Wed, 1 Jul 2020 21:39:02 -0700 Subject: [PATCH] Add TruncatedSubStorage --- src/LibHac/Fs/SubStorage.cs | 31 +++++++++++++++-- src/LibHac/FsSystem/TruncatedSubStorage.cs | 39 ++++++++++++++++++++++ 2 files changed, 68 insertions(+), 2 deletions(-) create mode 100644 src/LibHac/FsSystem/TruncatedSubStorage.cs diff --git a/src/LibHac/Fs/SubStorage.cs b/src/LibHac/Fs/SubStorage.cs index 5627726f..ff0103da 100644 --- a/src/LibHac/Fs/SubStorage.cs +++ b/src/LibHac/Fs/SubStorage.cs @@ -6,11 +6,38 @@ namespace LibHac.Fs public class SubStorage : IStorage { private ReferenceCountedDisposable SharedBaseStorage { get; set; } - private IStorage BaseStorage { get; } - private long Offset { get; } + protected IStorage BaseStorage { get; private set; } + private long Offset { get; set; } private long Size { get; set; } private bool IsResizable { get; set; } + public SubStorage() + { + BaseStorage = null; + Offset = 0; + Size = 0; + IsResizable = false; + } + + public SubStorage(SubStorage other) + { + BaseStorage = other.BaseStorage; + Offset = other.Offset; + Size = other.Size; + IsResizable = other.IsResizable; + } + + public void InitializeFrom(SubStorage other) + { + if (this != other) + { + BaseStorage = other.BaseStorage; + Offset = other.Offset; + Size = other.Size; + IsResizable = other.IsResizable; + } + } + public SubStorage(IStorage baseStorage, long offset, long size) { BaseStorage = baseStorage; diff --git a/src/LibHac/FsSystem/TruncatedSubStorage.cs b/src/LibHac/FsSystem/TruncatedSubStorage.cs new file mode 100644 index 00000000..fcb25b1c --- /dev/null +++ b/src/LibHac/FsSystem/TruncatedSubStorage.cs @@ -0,0 +1,39 @@ +using System; +using LibHac.Fs; + +namespace LibHac.FsSystem +{ + public class TruncatedSubStorage : SubStorage + { + public TruncatedSubStorage() { } + public TruncatedSubStorage(SubStorage other) : base(other) { } + + protected override Result DoRead(long offset, Span destination) + { + if (destination.Length == 0) + return Result.Success; + + Result rc = BaseStorage.GetSize(out long baseStorageSize); + if (rc.IsFailure()) return rc; + + long availableSize = baseStorageSize - offset; + long sizeToRead = Math.Min(destination.Length, availableSize); + + return base.DoRead(offset, destination.Slice(0, (int)sizeToRead)); + } + + protected override Result DoWrite(long offset, ReadOnlySpan source) + { + if (source.Length == 0) + return Result.Success; + + Result rc = BaseStorage.GetSize(out long baseStorageSize); + if (rc.IsFailure()) return rc; + + long availableSize = baseStorageSize - offset; + long sizeToWrite = Math.Min(source.Length, availableSize); + + return base.DoWrite(offset, source.Slice(0, (int)sizeToWrite)); + } + } +}