mirror of
https://github.com/Thealexbarney/LibHac.git
synced 2025-02-09 13:14:46 +01:00
Remove old SubStorage
This commit is contained in:
parent
f02c84e8dd
commit
e9c38dc7ba
@ -3,7 +3,7 @@ using LibHac.Diag;
|
|||||||
|
|
||||||
namespace LibHac.Fs
|
namespace LibHac.Fs
|
||||||
{
|
{
|
||||||
public class SubStorage2 : IStorage
|
public class SubStorage : IStorage
|
||||||
{
|
{
|
||||||
private ReferenceCountedDisposable<IStorage> SharedBaseStorage { get; set; }
|
private ReferenceCountedDisposable<IStorage> SharedBaseStorage { get; set; }
|
||||||
private IStorage BaseStorage { get; }
|
private IStorage BaseStorage { get; }
|
||||||
@ -11,7 +11,7 @@ namespace LibHac.Fs
|
|||||||
private long Size { get; set; }
|
private long Size { get; set; }
|
||||||
private bool IsResizable { get; set; }
|
private bool IsResizable { get; set; }
|
||||||
|
|
||||||
public SubStorage2(IStorage baseStorage, long offset, long size)
|
public SubStorage(IStorage baseStorage, long offset, long size)
|
||||||
{
|
{
|
||||||
BaseStorage = baseStorage;
|
BaseStorage = baseStorage;
|
||||||
Offset = offset;
|
Offset = offset;
|
||||||
@ -23,7 +23,7 @@ namespace LibHac.Fs
|
|||||||
Assert.AssertTrue(Size >= 0);
|
Assert.AssertTrue(Size >= 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
public SubStorage2(ReferenceCountedDisposable<IStorage> sharedBaseStorage, long offset, long size)
|
public SubStorage(ReferenceCountedDisposable<IStorage> sharedBaseStorage, long offset, long size)
|
||||||
{
|
{
|
||||||
SharedBaseStorage = sharedBaseStorage.AddReference();
|
SharedBaseStorage = sharedBaseStorage.AddReference();
|
||||||
BaseStorage = SharedBaseStorage.Target;
|
BaseStorage = SharedBaseStorage.Target;
|
||||||
@ -36,7 +36,7 @@ namespace LibHac.Fs
|
|||||||
Assert.AssertTrue(Size >= 0);
|
Assert.AssertTrue(Size >= 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
public SubStorage2(SubStorage2 subStorage, long offset, long size)
|
public SubStorage(SubStorage subStorage, long offset, long size)
|
||||||
{
|
{
|
||||||
BaseStorage = subStorage.BaseStorage;
|
BaseStorage = subStorage.BaseStorage;
|
||||||
Offset = subStorage.Offset + offset;
|
Offset = subStorage.Offset + offset;
|
@ -26,7 +26,7 @@ namespace LibHac.FsService.Creators
|
|||||||
Result rc = GameCard.GetCardInfo(out GameCardInfo cardInfo, handle);
|
Result rc = GameCard.GetCardInfo(out GameCardInfo cardInfo, handle);
|
||||||
if (rc.IsFailure()) return rc;
|
if (rc.IsFailure()) return rc;
|
||||||
|
|
||||||
storage = new SubStorage2(baseStorage, 0, cardInfo.SecureAreaOffset);
|
storage = new SubStorage(baseStorage, 0, cardInfo.SecureAreaOffset);
|
||||||
return Result.Success;
|
return Result.Success;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -53,7 +53,7 @@ namespace LibHac.FsService.Creators
|
|||||||
rc = GameCard.GetCardInfo(out GameCardInfo cardInfo, handle);
|
rc = GameCard.GetCardInfo(out GameCardInfo cardInfo, handle);
|
||||||
if (rc.IsFailure()) return rc;
|
if (rc.IsFailure()) return rc;
|
||||||
|
|
||||||
storage = new SubStorage2(baseStorage, cardInfo.SecureAreaOffset, cardInfo.SecureAreaSize);
|
storage = new SubStorage(baseStorage, cardInfo.SecureAreaOffset, cardInfo.SecureAreaSize);
|
||||||
return Result.Success;
|
return Result.Success;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -21,7 +21,7 @@ namespace LibHac.FsSystem
|
|||||||
public int Generation;
|
public int Generation;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Aes128CtrExStorage(IStorage baseStorage, SubStorage2 nodeStorage, SubStorage2 entryStorage,
|
public Aes128CtrExStorage(IStorage baseStorage, SubStorage nodeStorage, SubStorage entryStorage,
|
||||||
int entryCount, byte[] key, byte[] counter, bool leaveOpen)
|
int entryCount, byte[] key, byte[] counter, bool leaveOpen)
|
||||||
: base(baseStorage, key, counter, leaveOpen)
|
: base(baseStorage, key, counter, leaveOpen)
|
||||||
{
|
{
|
||||||
|
@ -19,8 +19,8 @@ namespace LibHac.FsSystem
|
|||||||
|
|
||||||
private static int NodeHeaderSize => Unsafe.SizeOf<NodeHeader>();
|
private static int NodeHeaderSize => Unsafe.SizeOf<NodeHeader>();
|
||||||
|
|
||||||
private SubStorage2 NodeStorage { get; set; }
|
private SubStorage NodeStorage { get; set; }
|
||||||
private SubStorage2 EntryStorage { get; set; }
|
private SubStorage EntryStorage { get; set; }
|
||||||
|
|
||||||
private NodeBuffer _nodeL1 = new NodeBuffer();
|
private NodeBuffer _nodeL1 = new NodeBuffer();
|
||||||
|
|
||||||
@ -31,7 +31,7 @@ namespace LibHac.FsSystem
|
|||||||
private long StartOffset { get; set; }
|
private long StartOffset { get; set; }
|
||||||
private long EndOffset { get; set; }
|
private long EndOffset { get; set; }
|
||||||
|
|
||||||
public Result Initialize(SubStorage2 nodeStorage, SubStorage2 entryStorage, int nodeSize, int entrySize,
|
public Result Initialize(SubStorage nodeStorage, SubStorage entryStorage, int nodeSize, int entrySize,
|
||||||
int entryCount)
|
int entryCount)
|
||||||
{
|
{
|
||||||
Assert.AssertTrue(entrySize >= sizeof(long));
|
Assert.AssertTrue(entrySize >= sizeof(long));
|
||||||
@ -598,7 +598,7 @@ namespace LibHac.FsSystem
|
|||||||
// Calculate node extents.
|
// Calculate node extents.
|
||||||
long nodeSize = Tree.NodeSize;
|
long nodeSize = Tree.NodeSize;
|
||||||
long nodeOffset = (nodeIndex + 1) * nodeSize;
|
long nodeOffset = (nodeIndex + 1) * nodeSize;
|
||||||
SubStorage2 storage = Tree.NodeStorage;
|
SubStorage storage = Tree.NodeStorage;
|
||||||
|
|
||||||
// Read the node.
|
// Read the node.
|
||||||
Result rc = storage.Read(nodeOffset, buffer.Slice(0, (int)nodeSize));
|
Result rc = storage.Read(nodeOffset, buffer.Slice(0, (int)nodeSize));
|
||||||
@ -637,7 +637,7 @@ namespace LibHac.FsSystem
|
|||||||
long entrySize = Tree.EntrySize;
|
long entrySize = Tree.EntrySize;
|
||||||
long entrySetSize = Tree.NodeSize;
|
long entrySetSize = Tree.NodeSize;
|
||||||
long entrySetOffset = entrySetIndex * entrySetSize;
|
long entrySetOffset = entrySetIndex * entrySetSize;
|
||||||
SubStorage2 storage = Tree.EntryStorage;
|
SubStorage storage = Tree.EntryStorage;
|
||||||
|
|
||||||
// Read the entry set.
|
// Read the entry set.
|
||||||
Result rc = storage.Read(entrySetOffset, buffer.Slice(0, (int)entrySetSize));
|
Result rc = storage.Read(entrySetOffset, buffer.Slice(0, (int)entrySetSize));
|
||||||
|
@ -11,8 +11,8 @@ namespace LibHac.FsSystem
|
|||||||
{
|
{
|
||||||
public class Builder
|
public class Builder
|
||||||
{
|
{
|
||||||
private SubStorage2 NodeStorage { get; set; }
|
private SubStorage NodeStorage { get; set; }
|
||||||
private SubStorage2 EntryStorage { get; set; }
|
private SubStorage EntryStorage { get; set; }
|
||||||
|
|
||||||
private NodeBuffer _l1Node = new NodeBuffer();
|
private NodeBuffer _l1Node = new NodeBuffer();
|
||||||
private NodeBuffer _l2Node = new NodeBuffer();
|
private NodeBuffer _l2Node = new NodeBuffer();
|
||||||
@ -31,14 +31,14 @@ namespace LibHac.FsSystem
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Initializes the bucket tree builder.
|
/// Initializes the bucket tree builder.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="headerStorage">The <see cref="SubStorage2"/> the tree's header will be written to.Must be at least the size in bytes returned by <see cref="QueryHeaderStorageSize"/>.</param>
|
/// <param name="headerStorage">The <see cref="SubStorage"/> the tree's header will be written to.Must be at least the size in bytes returned by <see cref="QueryHeaderStorageSize"/>.</param>
|
||||||
/// <param name="nodeStorage">The <see cref="SubStorage2"/> the tree's nodes will be written to. Must be at least the size in bytes returned by <see cref="QueryNodeStorageSize"/>.</param>
|
/// <param name="nodeStorage">The <see cref="SubStorage"/> the tree's nodes will be written to. Must be at least the size in bytes returned by <see cref="QueryNodeStorageSize"/>.</param>
|
||||||
/// <param name="entryStorage">The <see cref="SubStorage2"/> the tree's entries will be written to. Must be at least the size in bytes returned by <see cref="QueryEntryStorageSize"/>.</param>
|
/// <param name="entryStorage">The <see cref="SubStorage"/> the tree's entries will be written to. Must be at least the size in bytes returned by <see cref="QueryEntryStorageSize"/>.</param>
|
||||||
/// <param name="nodeSize">The size of each node in the bucket tree. Must be a power of 2.</param>
|
/// <param name="nodeSize">The size of each node in the bucket tree. Must be a power of 2.</param>
|
||||||
/// <param name="entrySize">The size of each entry that will be stored in the bucket tree.</param>
|
/// <param name="entrySize">The size of each entry that will be stored in the bucket tree.</param>
|
||||||
/// <param name="entryCount">The exact number of entries that will be added to the bucket tree.</param>
|
/// <param name="entryCount">The exact number of entries that will be added to the bucket tree.</param>
|
||||||
/// <returns>The <see cref="Result"/> of the operation.</returns>
|
/// <returns>The <see cref="Result"/> of the operation.</returns>
|
||||||
public Result Initialize(SubStorage2 headerStorage, SubStorage2 nodeStorage, SubStorage2 entryStorage,
|
public Result Initialize(SubStorage headerStorage, SubStorage nodeStorage, SubStorage entryStorage,
|
||||||
int nodeSize, int entrySize, int entryCount)
|
int nodeSize, int entrySize, int entryCount)
|
||||||
{
|
{
|
||||||
Assert.AssertTrue(entrySize >= sizeof(long));
|
Assert.AssertTrue(entrySize >= sizeof(long));
|
||||||
|
@ -13,7 +13,7 @@ namespace LibHac.FsSystem
|
|||||||
public static readonly int NodeSize = 1024 * 16;
|
public static readonly int NodeSize = 1024 * 16;
|
||||||
|
|
||||||
private BucketTree Table { get; } = new BucketTree();
|
private BucketTree Table { get; } = new BucketTree();
|
||||||
private SubStorage2[] DataStorage { get; } = new SubStorage2[StorageCount];
|
private SubStorage[] DataStorage { get; } = new SubStorage[StorageCount];
|
||||||
|
|
||||||
[StructLayout(LayoutKind.Sequential, Size = 0x14, Pack = 4)]
|
[StructLayout(LayoutKind.Sequential, Size = 0x14, Pack = 4)]
|
||||||
public struct Entry
|
public struct Entry
|
||||||
@ -39,7 +39,7 @@ namespace LibHac.FsSystem
|
|||||||
|
|
||||||
public bool IsInitialized() => Table.IsInitialized();
|
public bool IsInitialized() => Table.IsInitialized();
|
||||||
|
|
||||||
public Result Initialize(SubStorage2 tableStorage)
|
public Result Initialize(SubStorage tableStorage)
|
||||||
{
|
{
|
||||||
// Read and verify the bucket tree header.
|
// Read and verify the bucket tree header.
|
||||||
// note: skip init
|
// note: skip init
|
||||||
@ -58,18 +58,18 @@ namespace LibHac.FsSystem
|
|||||||
long entryStorageOffset = nodeStorageOffset + nodeStorageSize;
|
long entryStorageOffset = nodeStorageOffset + nodeStorageSize;
|
||||||
|
|
||||||
// Initialize.
|
// Initialize.
|
||||||
var nodeStorage = new SubStorage2(tableStorage, nodeStorageOffset, nodeStorageSize);
|
var nodeStorage = new SubStorage(tableStorage, nodeStorageOffset, nodeStorageSize);
|
||||||
var entryStorage = new SubStorage2(tableStorage, entryStorageOffset, entryStorageSize);
|
var entryStorage = new SubStorage(tableStorage, entryStorageOffset, entryStorageSize);
|
||||||
|
|
||||||
return Initialize(nodeStorage, entryStorage, header.EntryCount);
|
return Initialize(nodeStorage, entryStorage, header.EntryCount);
|
||||||
}
|
}
|
||||||
|
|
||||||
public Result Initialize(SubStorage2 nodeStorage, SubStorage2 entryStorage, int entryCount)
|
public Result Initialize(SubStorage nodeStorage, SubStorage entryStorage, int entryCount)
|
||||||
{
|
{
|
||||||
return Table.Initialize(nodeStorage, entryStorage, NodeSize, Unsafe.SizeOf<Entry>(), entryCount);
|
return Table.Initialize(nodeStorage, entryStorage, NodeSize, Unsafe.SizeOf<Entry>(), entryCount);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void SetStorage(int index, SubStorage2 storage)
|
public void SetStorage(int index, SubStorage storage)
|
||||||
{
|
{
|
||||||
Assert.InRange(index, 0, StorageCount);
|
Assert.InRange(index, 0, StorageCount);
|
||||||
DataStorage[index] = storage;
|
DataStorage[index] = storage;
|
||||||
@ -78,7 +78,7 @@ namespace LibHac.FsSystem
|
|||||||
public void SetStorage(int index, IStorage storage, long offset, long size)
|
public void SetStorage(int index, IStorage storage, long offset, long size)
|
||||||
{
|
{
|
||||||
Assert.InRange(index, 0, StorageCount);
|
Assert.InRange(index, 0, StorageCount);
|
||||||
DataStorage[index] = new SubStorage2(storage, offset, size);
|
DataStorage[index] = new SubStorage(storage, offset, size);
|
||||||
}
|
}
|
||||||
|
|
||||||
public Result GetEntryList(Span<Entry> entryBuffer, out int outputEntryCount, long offset, long size)
|
public Result GetEntryList(Span<Entry> entryBuffer, out int outputEntryCount, long offset, long size)
|
||||||
@ -280,7 +280,7 @@ namespace LibHac.FsSystem
|
|||||||
Assert.AssertTrue(currentSize <= size);
|
Assert.AssertTrue(currentSize <= size);
|
||||||
|
|
||||||
{
|
{
|
||||||
SubStorage2 currentStorage = DataStorage[currentEntry.StorageIndex];
|
SubStorage currentStorage = DataStorage[currentEntry.StorageIndex];
|
||||||
|
|
||||||
// Get the current data storage's size.
|
// Get the current data storage's size.
|
||||||
rc = currentStorage.GetSize(out long currentDataStorageSize);
|
rc = currentStorage.GetSize(out long currentDataStorageSize);
|
||||||
|
@ -194,7 +194,7 @@ namespace LibHac.FsSystem.NcaUtils
|
|||||||
byte[] counterEx = Aes128CtrStorage.CreateCounter(fsHeader.Counter, sectionOffset);
|
byte[] counterEx = Aes128CtrStorage.CreateCounter(fsHeader.Counter, sectionOffset);
|
||||||
|
|
||||||
IStorage bucketTreeData = new CachedStorage(new Aes128CtrStorage(baseStorage.Slice(bktrOffset, bktrSize), key, counter, true), 4, true);
|
IStorage bucketTreeData = new CachedStorage(new Aes128CtrStorage(baseStorage.Slice(bktrOffset, bktrSize), key, counter, true), 4, true);
|
||||||
var encryptionBucketTreeData = new SubStorage2(bucketTreeData,
|
var encryptionBucketTreeData = new SubStorage(bucketTreeData,
|
||||||
info.EncryptionTreeOffset - bktrOffset, sectionSize - info.EncryptionTreeOffset);
|
info.EncryptionTreeOffset - bktrOffset, sectionSize - info.EncryptionTreeOffset);
|
||||||
|
|
||||||
var cachedBucketTreeData = new CachedStorage(encryptionBucketTreeData, IndirectStorage.NodeSize, 6, true);
|
var cachedBucketTreeData = new CachedStorage(encryptionBucketTreeData, IndirectStorage.NodeSize, 6, true);
|
||||||
@ -204,8 +204,8 @@ namespace LibHac.FsSystem.NcaUtils
|
|||||||
long nodeStorageSize = IndirectStorage.QueryNodeStorageSize(treeHeader.EntryCount);
|
long nodeStorageSize = IndirectStorage.QueryNodeStorageSize(treeHeader.EntryCount);
|
||||||
long entryStorageSize = IndirectStorage.QueryEntryStorageSize(treeHeader.EntryCount);
|
long entryStorageSize = IndirectStorage.QueryEntryStorageSize(treeHeader.EntryCount);
|
||||||
|
|
||||||
var tableNodeStorage = new SubStorage2(cachedBucketTreeData, 0, nodeStorageSize);
|
var tableNodeStorage = new SubStorage(cachedBucketTreeData, 0, nodeStorageSize);
|
||||||
var tableEntryStorage = new SubStorage2(cachedBucketTreeData, nodeStorageSize, entryStorageSize);
|
var tableEntryStorage = new SubStorage(cachedBucketTreeData, nodeStorageSize, entryStorageSize);
|
||||||
|
|
||||||
IStorage decStorage = new Aes128CtrExStorage(baseStorage.Slice(0, dataSize), tableNodeStorage,
|
IStorage decStorage = new Aes128CtrExStorage(baseStorage.Slice(0, dataSize), tableNodeStorage,
|
||||||
tableEntryStorage, treeHeader.EntryCount, key, counterEx, true);
|
tableEntryStorage, treeHeader.EntryCount, key, counterEx, true);
|
||||||
@ -242,11 +242,11 @@ namespace LibHac.FsSystem.NcaUtils
|
|||||||
long nodeStorageSize = IndirectStorage.QueryNodeStorageSize(treeHeader.EntryCount);
|
long nodeStorageSize = IndirectStorage.QueryNodeStorageSize(treeHeader.EntryCount);
|
||||||
long entryStorageSize = IndirectStorage.QueryEntryStorageSize(treeHeader.EntryCount);
|
long entryStorageSize = IndirectStorage.QueryEntryStorageSize(treeHeader.EntryCount);
|
||||||
|
|
||||||
var relocationTableStorage = new SubStorage2(patchStorage, patchInfo.RelocationTreeOffset, patchInfo.RelocationTreeSize);
|
var relocationTableStorage = new SubStorage(patchStorage, patchInfo.RelocationTreeOffset, patchInfo.RelocationTreeSize);
|
||||||
var cachedTableStorage = new CachedStorage(relocationTableStorage, IndirectStorage.NodeSize, 4, true);
|
var cachedTableStorage = new CachedStorage(relocationTableStorage, IndirectStorage.NodeSize, 4, true);
|
||||||
|
|
||||||
var tableNodeStorage = new SubStorage2(cachedTableStorage, 0, nodeStorageSize);
|
var tableNodeStorage = new SubStorage(cachedTableStorage, 0, nodeStorageSize);
|
||||||
var tableEntryStorage = new SubStorage2(cachedTableStorage, nodeStorageSize, entryStorageSize);
|
var tableEntryStorage = new SubStorage(cachedTableStorage, nodeStorageSize, entryStorageSize);
|
||||||
|
|
||||||
var storage = new IndirectStorage();
|
var storage = new IndirectStorage();
|
||||||
storage.Initialize(tableNodeStorage, tableEntryStorage, treeHeader.EntryCount).ThrowIfFailure();
|
storage.Initialize(tableNodeStorage, tableEntryStorage, treeHeader.EntryCount).ThrowIfFailure();
|
||||||
|
@ -16,8 +16,8 @@ namespace LibHac.FsSystem.Save
|
|||||||
|
|
||||||
public AllocationTableHeader Header { get; }
|
public AllocationTableHeader Header { get; }
|
||||||
|
|
||||||
public IStorage GetBaseStorage() => BaseStorage.AsReadOnly();
|
public IStorage GetBaseStorage() => BaseStorage;
|
||||||
public IStorage GetHeaderStorage() => HeaderStorage.AsReadOnly();
|
public IStorage GetHeaderStorage() => HeaderStorage;
|
||||||
|
|
||||||
public AllocationTable(IStorage storage, IStorage header)
|
public AllocationTable(IStorage storage, IStorage header)
|
||||||
{
|
{
|
||||||
|
@ -52,11 +52,11 @@ namespace LibHac.FsSystem.Save
|
|||||||
return map;
|
return map;
|
||||||
}
|
}
|
||||||
|
|
||||||
public IStorage GetMapStorage() => MapStorage.AsReadOnly();
|
public IStorage GetMapStorage() => MapStorage;
|
||||||
public IStorage GetHeaderStorage() => HeaderStorage.AsReadOnly();
|
public IStorage GetHeaderStorage() => HeaderStorage;
|
||||||
public IStorage GetModifiedPhysicalBlocksStorage() => ModifiedPhysicalBlocks.AsReadOnly();
|
public IStorage GetModifiedPhysicalBlocksStorage() => ModifiedPhysicalBlocks;
|
||||||
public IStorage GetModifiedVirtualBlocksStorage() => ModifiedVirtualBlocks.AsReadOnly();
|
public IStorage GetModifiedVirtualBlocksStorage() => ModifiedVirtualBlocks;
|
||||||
public IStorage GetFreeBlocksStorage() => FreeBlocks.AsReadOnly();
|
public IStorage GetFreeBlocksStorage() => FreeBlocks;
|
||||||
|
|
||||||
public void FsTrim()
|
public void FsTrim()
|
||||||
{
|
{
|
||||||
|
@ -118,8 +118,8 @@ namespace LibHac.FsSystem.Save
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public IStorage GetBaseStorage() => BaseStorage.AsReadOnly();
|
public IStorage GetBaseStorage() => BaseStorage;
|
||||||
public IStorage GetHeaderStorage() => HeaderStorage.AsReadOnly();
|
public IStorage GetHeaderStorage() => HeaderStorage;
|
||||||
|
|
||||||
public void FsTrim()
|
public void FsTrim()
|
||||||
{
|
{
|
||||||
|
@ -138,9 +138,9 @@ namespace LibHac.FsSystem.Save
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public IStorage GetBaseStorage() => BaseStorage.AsReadOnly();
|
public IStorage GetBaseStorage() => BaseStorage;
|
||||||
public IStorage GetHeaderStorage() => HeaderStorage.AsReadOnly();
|
public IStorage GetHeaderStorage() => HeaderStorage;
|
||||||
public IStorage GetMapEntryStorage() => MapEntryStorage.AsReadOnly();
|
public IStorage GetMapEntryStorage() => MapEntryStorage;
|
||||||
|
|
||||||
private static RemapSegment[] InitSegments(RemapHeader header, MapEntry[] mapEntries)
|
private static RemapSegment[] InitSegments(RemapHeader header, MapEntry[] mapEntries)
|
||||||
{
|
{
|
||||||
|
@ -261,8 +261,8 @@ namespace LibHac.FsSystem.Save
|
|||||||
return Result.Success;
|
return Result.Success;
|
||||||
}
|
}
|
||||||
|
|
||||||
public IStorage GetBaseStorage() => BaseStorage.AsReadOnly();
|
public IStorage GetBaseStorage() => BaseStorage;
|
||||||
public IStorage GetHeaderStorage() => HeaderStorage.AsReadOnly();
|
public IStorage GetHeaderStorage() => HeaderStorage;
|
||||||
|
|
||||||
public void FsTrim()
|
public void FsTrim()
|
||||||
{
|
{
|
||||||
|
@ -54,18 +54,15 @@ namespace LibHac.FsSystem
|
|||||||
|
|
||||||
public static IStorage Slice(this IStorage storage, long start, long length, bool leaveOpen)
|
public static IStorage Slice(this IStorage storage, long start, long length, bool leaveOpen)
|
||||||
{
|
{
|
||||||
return new SubStorage(storage, start, length, leaveOpen);
|
if (!leaveOpen)
|
||||||
}
|
{
|
||||||
|
return new SubStorage(storage, start, length);
|
||||||
|
}
|
||||||
|
|
||||||
public static IStorage AsReadOnly(this IStorage storage)
|
using (var sharedStorage = new ReferenceCountedDisposable<IStorage>(storage))
|
||||||
{
|
{
|
||||||
return storage.AsReadOnly(true);
|
return new SubStorage(sharedStorage, start, length);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static IStorage AsReadOnly(this IStorage storage, bool leaveOpen)
|
|
||||||
{
|
|
||||||
storage.GetSize(out long storageSize).ThrowIfFailure();
|
|
||||||
return new SubStorage(storage, 0, storageSize, leaveOpen, FileAccess.Read);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Stream AsStream(this IStorage storage) => new StorageStream(storage, FileAccess.ReadWrite, true);
|
public static Stream AsStream(this IStorage storage) => new StorageStream(storage, FileAccess.ReadWrite, true);
|
||||||
|
@ -1,101 +0,0 @@
|
|||||||
using System;
|
|
||||||
using System.IO;
|
|
||||||
using LibHac.Fs;
|
|
||||||
|
|
||||||
namespace LibHac.FsSystem
|
|
||||||
{
|
|
||||||
public class SubStorage : IStorage
|
|
||||||
{
|
|
||||||
private IStorage BaseStorage { get; }
|
|
||||||
private long Offset { get; }
|
|
||||||
private FileAccess Access { get; } = FileAccess.ReadWrite;
|
|
||||||
private long Length { get; set; }
|
|
||||||
private bool LeaveOpen { get; }
|
|
||||||
|
|
||||||
public SubStorage(IStorage baseStorage, long offset, long length)
|
|
||||||
{
|
|
||||||
BaseStorage = baseStorage;
|
|
||||||
Offset = offset;
|
|
||||||
Length = length;
|
|
||||||
}
|
|
||||||
|
|
||||||
public SubStorage(SubStorage baseStorage, long offset, long length)
|
|
||||||
{
|
|
||||||
BaseStorage = baseStorage.BaseStorage;
|
|
||||||
Offset = baseStorage.Offset + offset;
|
|
||||||
Length = length;
|
|
||||||
}
|
|
||||||
|
|
||||||
public SubStorage(IStorage baseStorage, long offset, long length, bool leaveOpen)
|
|
||||||
: this(baseStorage, offset, length)
|
|
||||||
{
|
|
||||||
LeaveOpen = leaveOpen;
|
|
||||||
}
|
|
||||||
|
|
||||||
public SubStorage(IStorage baseStorage, long offset, long length, bool leaveOpen, FileAccess access)
|
|
||||||
: this(baseStorage, offset, length, leaveOpen)
|
|
||||||
{
|
|
||||||
Access = access;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected override Result DoRead(long offset, Span<byte> destination)
|
|
||||||
{
|
|
||||||
if ((Access & FileAccess.Read) == 0) throw new InvalidOperationException("Storage is not readable");
|
|
||||||
return BaseStorage.Read(offset + Offset, destination);
|
|
||||||
}
|
|
||||||
|
|
||||||
protected override Result DoWrite(long offset, ReadOnlySpan<byte> source)
|
|
||||||
{
|
|
||||||
if ((Access & FileAccess.Write) == 0) throw new InvalidOperationException("Storage is not writable");
|
|
||||||
return BaseStorage.Write(offset + Offset, source);
|
|
||||||
}
|
|
||||||
|
|
||||||
protected override Result DoFlush()
|
|
||||||
{
|
|
||||||
return BaseStorage.Flush();
|
|
||||||
}
|
|
||||||
|
|
||||||
protected override Result DoGetSize(out long size)
|
|
||||||
{
|
|
||||||
size = Length;
|
|
||||||
return Result.Success;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected override Result DoSetSize(long size)
|
|
||||||
{
|
|
||||||
if (BaseStorage == null) return ResultFs.NotInitialized.Log();
|
|
||||||
|
|
||||||
// todo: Add IsResizable member
|
|
||||||
// if (!IsResizable) return ResultFs.SubStorageNotResizable.Log();
|
|
||||||
|
|
||||||
if (Offset < 0 || size < 0) return ResultFs.InvalidSize.Log();
|
|
||||||
|
|
||||||
Result rc = BaseStorage.GetSize(out long baseSize);
|
|
||||||
if (rc.IsFailure()) return rc;
|
|
||||||
|
|
||||||
if (baseSize != Offset + Length)
|
|
||||||
{
|
|
||||||
// SubStorage cannot be resized unless it is located at the end of the base storage.
|
|
||||||
return ResultFs.UnsupportedOperationInResizableSubStorageSetSize.Log();
|
|
||||||
}
|
|
||||||
|
|
||||||
rc = BaseStorage.SetSize(Offset + size);
|
|
||||||
if (rc.IsFailure()) return rc;
|
|
||||||
|
|
||||||
Length = size;
|
|
||||||
|
|
||||||
return Result.Success;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected override void Dispose(bool disposing)
|
|
||||||
{
|
|
||||||
if (disposing)
|
|
||||||
{
|
|
||||||
if (!LeaveOpen)
|
|
||||||
{
|
|
||||||
BaseStorage?.Dispose();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -75,7 +75,7 @@ namespace LibHac.Loader
|
|||||||
if (inputFileSize < kipFileSize)
|
if (inputFileSize < kipFileSize)
|
||||||
return ResultLibHac.InvalidKipFileSize.Log();
|
return ResultLibHac.InvalidKipFileSize.Log();
|
||||||
|
|
||||||
kipData = new SubStorage2(KipStorage, 0, kipFileSize);
|
kipData = new SubStorage(KipStorage, 0, kipFileSize);
|
||||||
return Result.Success;
|
return Result.Success;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user