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))
|
||||
{
|
||||
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];
|
||||
|
||||
if (!tableEntry.IsListStart())
|
||||
if (!tableEntry.IsListStart() && initialBlock != -1)
|
||||
{
|
||||
return false;
|
||||
return false;
|
||||
}
|
||||
|
||||
if (tableEntry.IsSingleBlockSegment())
|
||||
|
|
|
@ -152,6 +152,7 @@ namespace LibHac.IO.Save
|
|||
|
||||
public IStorage GetBaseStorage() => BaseStorage.AsReadOnly();
|
||||
public IStorage GetHeaderStorage() => HeaderStorage.AsReadOnly();
|
||||
public SaveFileEntry GetFileEntry(string path) => FileDictionary[path];
|
||||
|
||||
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>
|
||||
|
||||
<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.Memory" Version="4.5.2" />
|
||||
<PackageReference Include="System.Numerics.Vectors" Version="4.5.0" />
|
||||
<PackageReference Include="System.ValueTuple" Version="4.5.0" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup Condition=" '$(TargetFramework)' == 'netcoreapp2.1' ">
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
|
@ -151,6 +152,87 @@ namespace hactoolnet
|
|||
}
|
||||
|
||||
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