mirror of
https://github.com/Thealexbarney/LibHac.git
synced 2024-11-14 10:49:41 +01:00
Add code for printing save FAT chains
This commit is contained in:
parent
474e1e031e
commit
7bb99ff926
5 changed files with 106 additions and 5 deletions
|
@ -16,7 +16,7 @@ namespace LibHac.IO.Save
|
||||||
|
|
||||||
if (!BeginIteration(initialBlock))
|
if (!BeginIteration(initialBlock))
|
||||||
{
|
{
|
||||||
throw new ArgumentException($"Attempted to start FAT iteration from an invalid block. ({initialBlock}");
|
throw new ArgumentException($"Attempted to start FAT iteration from an invalid block. ({initialBlock})");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -24,9 +24,9 @@ namespace LibHac.IO.Save
|
||||||
{
|
{
|
||||||
AllocationTableEntry tableEntry = Fat.Entries[initialBlock + 1];
|
AllocationTableEntry tableEntry = Fat.Entries[initialBlock + 1];
|
||||||
|
|
||||||
if (!tableEntry.IsListStart())
|
if (!tableEntry.IsListStart() && initialBlock != -1)
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (tableEntry.IsSingleBlockSegment())
|
if (tableEntry.IsSingleBlockSegment())
|
||||||
|
|
|
@ -152,6 +152,7 @@ namespace LibHac.IO.Save
|
||||||
|
|
||||||
public IStorage GetBaseStorage() => BaseStorage.AsReadOnly();
|
public IStorage GetBaseStorage() => BaseStorage.AsReadOnly();
|
||||||
public IStorage GetHeaderStorage() => HeaderStorage.AsReadOnly();
|
public IStorage GetHeaderStorage() => HeaderStorage.AsReadOnly();
|
||||||
|
public SaveFileEntry GetFileEntry(string path) => FileDictionary[path];
|
||||||
|
|
||||||
private void ReadFileInfo()
|
private void ReadFileInfo()
|
||||||
{
|
{
|
||||||
|
|
17
src/LibHac/IO/Save/SaveExtensions.cs
Normal file
17
src/LibHac/IO/Save/SaveExtensions.cs
Normal file
|
@ -0,0 +1,17 @@
|
||||||
|
using System.Collections.Generic;
|
||||||
|
|
||||||
|
namespace LibHac.IO.Save
|
||||||
|
{
|
||||||
|
public static class SaveExtensions
|
||||||
|
{
|
||||||
|
public static IEnumerable<(int block, int length)> DumpChain(this AllocationTable table, int startBlock)
|
||||||
|
{
|
||||||
|
var iterator = new AllocationTableIterator(table, startBlock);
|
||||||
|
|
||||||
|
do
|
||||||
|
{
|
||||||
|
yield return (iterator.PhysicalBlock, iterator.CurrentSegmentSize);
|
||||||
|
} while (iterator.MoveNext());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -34,9 +34,10 @@
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
<ItemGroup Condition=" '$(TargetFramework)' == 'net46' ">
|
<ItemGroup Condition=" '$(TargetFramework)' == 'net46' ">
|
||||||
<PackageReference Include="System.Numerics.Vectors" Version="4.5.0" />
|
|
||||||
<PackageReference Include="System.Memory" Version="4.5.2" />
|
|
||||||
<PackageReference Include="System.Buffers" Version="4.5.0" />
|
<PackageReference Include="System.Buffers" Version="4.5.0" />
|
||||||
|
<PackageReference Include="System.Memory" Version="4.5.2" />
|
||||||
|
<PackageReference Include="System.Numerics.Vectors" Version="4.5.0" />
|
||||||
|
<PackageReference Include="System.ValueTuple" Version="4.5.0" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
<ItemGroup Condition=" '$(TargetFramework)' == 'netcoreapp2.1' ">
|
<ItemGroup Condition=" '$(TargetFramework)' == 'netcoreapp2.1' ">
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
using System;
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
|
@ -151,6 +152,87 @@ namespace hactoolnet
|
||||||
}
|
}
|
||||||
|
|
||||||
ctx.Logger.LogMessage(save.Print());
|
ctx.Logger.LogMessage(save.Print());
|
||||||
|
//ctx.Logger.LogMessage(PrintFatLayout(save));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// ReSharper disable once UnusedMember.Local
|
||||||
|
private static string PrintFatLayout(this SaveDataFileSystem save)
|
||||||
|
{
|
||||||
|
var sb = new StringBuilder();
|
||||||
|
|
||||||
|
foreach (DirectoryEntry entry in save.EnumerateEntries().Where(x => x.Type == DirectoryEntryType.File))
|
||||||
|
{
|
||||||
|
SaveFileEntry saveEntry = save.SaveDataFileSystemCore.GetFileEntry(entry.FullPath);
|
||||||
|
|
||||||
|
if (saveEntry.BlockIndex < 0) continue;
|
||||||
|
|
||||||
|
IEnumerable<(int block, int length)> chain = save.SaveDataFileSystemCore.AllocationTable.DumpChain(saveEntry.BlockIndex);
|
||||||
|
|
||||||
|
sb.AppendLine(entry.FullPath);
|
||||||
|
sb.AppendLine(PrintBlockChain(chain));
|
||||||
|
}
|
||||||
|
|
||||||
|
sb.AppendLine("Directory Table");
|
||||||
|
sb.AppendLine(PrintBlockChain(save.SaveDataFileSystemCore.AllocationTable.DumpChain(0)));
|
||||||
|
|
||||||
|
sb.AppendLine("File Table");
|
||||||
|
sb.AppendLine(PrintBlockChain(save.SaveDataFileSystemCore.AllocationTable.DumpChain(1)));
|
||||||
|
|
||||||
|
sb.AppendLine("Free blocks");
|
||||||
|
sb.AppendLine(PrintBlockChain(save.SaveDataFileSystemCore.AllocationTable.DumpChain(-1)));
|
||||||
|
|
||||||
|
return sb.ToString();
|
||||||
|
}
|
||||||
|
|
||||||
|
private static string PrintBlockChain(IEnumerable<(int block, int length)> chain)
|
||||||
|
{
|
||||||
|
var sb = new StringBuilder();
|
||||||
|
int segmentCount = 0;
|
||||||
|
int segmentStart = -1;
|
||||||
|
int segmentEnd = -1;
|
||||||
|
|
||||||
|
foreach ((int block, int length) in chain)
|
||||||
|
{
|
||||||
|
if (segmentStart == -1)
|
||||||
|
{
|
||||||
|
segmentStart = block;
|
||||||
|
segmentEnd = block + length - 1;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (block == segmentEnd + 1)
|
||||||
|
{
|
||||||
|
segmentEnd += length;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
PrintSegment();
|
||||||
|
|
||||||
|
segmentStart = block;
|
||||||
|
segmentEnd = block + length - 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
PrintSegment();
|
||||||
|
|
||||||
|
return sb.ToString();
|
||||||
|
|
||||||
|
void PrintSegment()
|
||||||
|
{
|
||||||
|
if (segmentCount > 0) sb.Append(", ");
|
||||||
|
|
||||||
|
if (segmentStart == segmentEnd)
|
||||||
|
{
|
||||||
|
sb.Append(segmentStart);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
sb.Append($"{segmentStart}-{segmentEnd}");
|
||||||
|
}
|
||||||
|
|
||||||
|
segmentCount++;
|
||||||
|
segmentStart = -1;
|
||||||
|
segmentEnd = -1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue