Use generics for save file table entries

This commit is contained in:
Alex Barney 2019-04-01 21:15:08 -05:00
parent 079ffa6d3b
commit 90fc0e096c
3 changed files with 27 additions and 35 deletions

View file

@ -5,13 +5,13 @@ namespace LibHac.IO.Save
{ {
public class HierarchicalSaveFileTable public class HierarchicalSaveFileTable
{ {
private SaveFsList<FileSaveEntry> FileTable { get; } private SaveFsList<TableEntry<SaveFileInfo>> FileTable { get; }
private SaveFsList<DirectorySaveEntry> DirectoryTable { get; } private SaveFsList<TableEntry<SaveFindPosition>> DirectoryTable { get; }
public HierarchicalSaveFileTable(IStorage dirTable, IStorage fileTable) public HierarchicalSaveFileTable(IStorage dirTable, IStorage fileTable)
{ {
FileTable = new SaveFsList<FileSaveEntry>(fileTable); FileTable = new SaveFsList<TableEntry<SaveFileInfo>>(fileTable);
DirectoryTable = new SaveFsList<DirectorySaveEntry>(dirTable); DirectoryTable = new SaveFsList<TableEntry<SaveFindPosition>>(dirTable);
} }
public bool TryOpenFile(string path, out SaveFileInfo fileInfo) public bool TryOpenFile(string path, out SaveFileInfo fileInfo)
@ -22,9 +22,9 @@ namespace LibHac.IO.Save
return false; return false;
} }
if (FileTable.TryGetValue(ref key, out FileSaveEntry value)) if (FileTable.TryGetValue(ref key, out TableEntry<SaveFileInfo> value))
{ {
fileInfo = value.Info; fileInfo = value.Value;
return true; return true;
} }
@ -43,7 +43,7 @@ namespace LibHac.IO.Save
Span<byte> nameBytes = stackalloc byte[FileTable.MaxNameLength]; Span<byte> nameBytes = stackalloc byte[FileTable.MaxNameLength];
bool success = FileTable.TryGetValue((int)position.NextFile, out FileSaveEntry entry, ref nameBytes); bool success = FileTable.TryGetValue((int)position.NextFile, out TableEntry<SaveFileInfo> entry, ref nameBytes);
// todo error message // todo error message
if (!success) if (!success)
@ -54,7 +54,7 @@ namespace LibHac.IO.Save
} }
position.NextFile = entry.NextSibling; position.NextFile = entry.NextSibling;
info = entry.Info; info = entry.Value;
name = Util.GetUtf8StringNullTerminated(nameBytes); name = Util.GetUtf8StringNullTerminated(nameBytes);
@ -69,9 +69,9 @@ namespace LibHac.IO.Save
return false; return false;
} }
Span<byte> nameBytes = stackalloc byte[FileTable.MaxNameLength]; Span<byte> nameBytes = stackalloc byte[DirectoryTable.MaxNameLength];
bool success = DirectoryTable.TryGetValue(position.NextDirectory, out DirectorySaveEntry entry, ref nameBytes); bool success = DirectoryTable.TryGetValue(position.NextDirectory, out TableEntry<SaveFindPosition> entry, ref nameBytes);
// todo error message // todo error message
if (!success) if (!success)
@ -110,15 +110,15 @@ namespace LibHac.IO.Save
if (index < 0) if (index < 0)
{ {
var newEntry = new DirectorySaveEntry(); var newEntry = new TableEntry<SaveFindPosition>();
index = DirectoryTable.Add(ref key, ref newEntry); index = DirectoryTable.Add(ref key, ref newEntry);
if (prevIndex > 0) if (prevIndex > 0)
{ {
DirectoryTable.GetValue(prevIndex, out DirectorySaveEntry parentEntry); DirectoryTable.GetValue(prevIndex, out TableEntry<SaveFindPosition> parentEntry);
newEntry.NextSibling = parentEntry.Pos.NextDirectory; newEntry.NextSibling = parentEntry.Value.NextDirectory;
parentEntry.Pos.NextDirectory = index; parentEntry.Value.NextDirectory = index;
DirectoryTable.SetValue(prevIndex, ref parentEntry); DirectoryTable.SetValue(prevIndex, ref parentEntry);
DirectoryTable.SetValue(index, ref newEntry); DirectoryTable.SetValue(index, ref newEntry);
@ -132,21 +132,21 @@ namespace LibHac.IO.Save
{ {
int index = FileTable.GetIndexFromKey(ref key).Index; int index = FileTable.GetIndexFromKey(ref key).Index;
var fileEntry = new FileSaveEntry(); var fileEntry = new TableEntry<SaveFileInfo>();
if (index < 0) if (index < 0)
{ {
index = FileTable.Add(ref key, ref fileEntry); index = FileTable.Add(ref key, ref fileEntry);
DirectoryTable.GetValue(prevIndex, out DirectorySaveEntry parentEntry); DirectoryTable.GetValue(prevIndex, out TableEntry<SaveFindPosition> parentEntry);
fileEntry.NextSibling = (int)parentEntry.Pos.NextFile; fileEntry.NextSibling = (int)parentEntry.Value.NextFile;
parentEntry.Pos.NextFile = index; parentEntry.Value.NextFile = index;
DirectoryTable.SetValue(prevIndex, ref parentEntry); DirectoryTable.SetValue(prevIndex, ref parentEntry);
} }
fileEntry.Info = fileInfo; fileEntry.Value = fileInfo;
FileTable.SetValue(index, ref fileEntry); FileTable.SetValue(index, ref fileEntry);
} }
} }
@ -159,9 +159,9 @@ namespace LibHac.IO.Save
return false; return false;
} }
if (DirectoryTable.TryGetValue(ref key, out DirectorySaveEntry value)) if (DirectoryTable.TryGetValue(ref key, out TableEntry<SaveFindPosition> entry))
{ {
position = value.Pos; position = entry.Value;
return true; return true;
} }
@ -187,19 +187,10 @@ namespace LibHac.IO.Save
} }
[StructLayout(LayoutKind.Sequential, Pack = 1)] [StructLayout(LayoutKind.Sequential, Pack = 1)]
private struct DirectorySaveEntry private struct TableEntry<T> where T : struct
{ {
public int NextSibling; public int NextSibling;
public SaveFindPosition Pos; public T Value;
public long Field10;
}
[StructLayout(LayoutKind.Sequential, Pack = 1)]
private struct FileSaveEntry
{
public int NextSibling;
public SaveFileInfo Info;
public long Field10;
} }
} }
} }

View file

@ -15,17 +15,18 @@ namespace LibHac.IO.Save
} }
} }
[StructLayout(LayoutKind.Sequential, Pack = 1)] [StructLayout(LayoutKind.Sequential, Pack = 1, Size = 0x14)]
public struct SaveFileInfo public struct SaveFileInfo
{ {
public int StartBlock; public int StartBlock;
public long Length; public long Length;
public long Reserved;
} }
/// <summary> /// <summary>
/// Represents the current position when enumerating a directory's contents. /// Represents the current position when enumerating a directory's contents.
/// </summary> /// </summary>
[StructLayout(LayoutKind.Sequential, Pack = 1)] [StructLayout(LayoutKind.Sequential, Pack = 1, Size = 0x14)]
public struct SaveFindPosition public struct SaveFindPosition
{ {
/// <summary>The ID of the next directory to be enumerated.</summary> /// <summary>The ID of the next directory to be enumerated.</summary>

View file

@ -5,7 +5,7 @@ using System.Runtime.InteropServices;
namespace LibHac.IO.Save namespace LibHac.IO.Save
{ {
internal class SaveFsList<T> where T : unmanaged internal class SaveFsList<T> where T : struct
{ {
private const int FreeListHeadIndex = 0; private const int FreeListHeadIndex = 0;
private const int UsedListHeadIndex = 1; private const int UsedListHeadIndex = 1;