pkNX/pkNX.Containers/Misc/AHTB.cs
Kurt 2578ba073c Refactoring
File scoped namespaces for all lib projects
netstandard2.0 => net6; now uniform. bye netframework!
2022-10-01 17:08:17 -07:00

64 lines
1.9 KiB
C#

using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Runtime.Serialization;
namespace pkNX.Containers;
/// <summary>
/// Asynchronous Hash TaBle containing file names and their corresponding hashes.
/// </summary>
/// <remarks>gfl::container::HashTable</remarks>
[Serializable]
public class AHTB : Dictionary<ulong, string>
{
public readonly AHTBEntry[] Entries;
public const uint Magic = 0x42544841; // AHTB
public static bool IsAHTB(byte[] data) => BitConverter.ToUInt32(data, 0) == Magic;
public AHTB(byte[] table)
{
using var ms = new MemoryStream(table);
using var br = new BinaryReader(ms);
var magic = br.ReadUInt32();
Debug.Assert(magic == Magic);
var count = br.ReadUInt32();
Entries = new AHTBEntry[count];
for (int i = 0; i < count; i++)
{
var e = new AHTBEntry(br);
Entries[i] = e;
if (!ContainsKey(e.Hash))
Add(e.Hash, e.Name);
}
}
public int GetIndex(ulong hash)
{
if (!TryGetValue(hash, out _))
return -1;
return Array.FindIndex(Entries, z => z.Hash == hash);
}
protected AHTB(SerializationInfo info, StreamingContext context)
{
Entries = this.Select(z => new AHTBEntry(z.Key, (ushort) z.Value.Length, 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);
public Dictionary<ulong, string> ToDictionary()
{
var map = new Dictionary<ulong, string>();
foreach (var entry in Entries)
map[entry.Hash] = entry.Name;
return map;
}
}