pkNX/pkNX.Containers/Misc/DatTable.cs
Kurt 38b784e19b Add handling for S/V load and data ripping
Co-Authored-By: SciresM <8676005+SciresM@users.noreply.github.com>
Co-Authored-By: Matt <17801814+sora10pls@users.noreply.github.com>
Co-Authored-By: Lusamine <30205550+Lusamine@users.noreply.github.com>
2022-11-24 15:30:03 -08:00

64 lines
1.9 KiB
C#

using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Runtime.Serialization;
namespace pkNX.Containers;
/// <summary>
/// Data Table for Hash->Value lookup
/// </summary>
/// <seealso cref="AHTB"/> for similar structure.
[Serializable]
public class DatTable : Dictionary<ulong, int>
{
// u32 count
// hash-val tuple[count]
// hash-val tuple: size=0x10
// - 8byte hash
// - u32(?) index
// - u32(?) unk
// pretty weak, don't call this if you aren't sure!
public static bool IsDatTable(ReadOnlySpan<byte> bytes) => IsDatTable(bytes, bytes.Length);
public static bool IsDatTable(ReadOnlySpan<byte> bytes, int len) => IsDatTable(System.Buffers.Binary.BinaryPrimitives.ReadInt32LittleEndian(bytes), len);
public static bool IsDatTable(int count, int len) => 4 + (count * 0x10) == len;
private readonly DatEntry[] Entries;
public DatTable(byte[] data)
{
using var ms = new MemoryStream(data);
using var br = new BinaryReader(ms);
var count = br.ReadInt32();
Entries = new DatEntry[count];
for (int i = 0; i < Entries.Length; i++)
{
var e = new DatEntry(br);
Entries[i] = e;
if (!ContainsKey(e.Hash))
Add(e.Hash, e.Value);
}
}
public int GetIndex(ulong hash)
{
if (!TryGetValue(hash, out _))
return -1;
return Array.FindIndex(Entries, z => z.Hash == hash);
}
protected DatTable(SerializationInfo info, StreamingContext context)
{
Entries = this.Select(z => new DatEntry(z.Key, z.Value)).ToArray();
}
public int GetIndex(string value) => GetIndex(FnvHash.HashFnv1a_64(value));
public IEnumerable<string> Summary => Entries.Select((z, i) => $"{i:0000}\t{z.Summary}");
public IEnumerable<string> ShortSummary => Entries.Select(z => z.Summary);
}