using System;
using System.Collections.Generic;
using System.IO;
namespace FSO.Files.HIT
{
///
/// HLS refers to two binary formats that both define a list of IDs, known as a hitlist.
/// One format is a Pascal string with a 4-byte, little-endian length, representing a
/// comma-seperated list of decimal values, or decimal ranges (e.g. "1025-1035"), succeeded
/// by a single LF newline.
///
public class Hitlist
{
private uint m_IDCount;
public List IDs; //variable length so it's easier to fill with ranges
///
/// Creates a new hitlist.
///
/// The data to create the hitlist from.
public Hitlist(byte[] Filedata)
{
Read(new MemoryStream(Filedata));
}
private void Read(Stream data)
{
BinaryReader Reader = new BinaryReader(data);
IDs = new List();
var VerOrCount = Reader.ReadUInt32();
try
{
if (VerOrCount == 1) //binary format, no hitlist is ever going to have length 1... (i hope)
{
m_IDCount = Reader.ReadUInt32();
for (int i = 0; i < m_IDCount; i++)
IDs.Add(Reader.ReadUInt32());
Reader.Close();
}
else
{
var str = new string(Reader.ReadChars((int)VerOrCount));
Populate(str);
}
}
catch
{
Reader.BaseStream.Seek(4, SeekOrigin.Begin); //attempt 3rd mystery format, count+int32
for (int i = 0; i < VerOrCount; i++)
IDs.Add(Reader.ReadUInt32());
}
}
public Hitlist()
{
IDs = new List();
}
public void Populate(string str)
{
var commaSplit = str.Split(',');
for (int i = 0; i < commaSplit.Length; i++)
{
var dashSplit = commaSplit[i].Split('-');
if (dashSplit.Length > 1)
{ //range, parse two values and fill in the gap
var min = Convert.ToUInt32(dashSplit[0]);
var max = Convert.ToUInt32(dashSplit[1]);
for (uint j = min; j <= max; j++)
{
IDs.Add(j);
}
}
else
{ //literal entry, add to list
IDs.Add(Convert.ToUInt32(commaSplit[i]));
}
}
}
public static Hitlist HitlistFromString(string str)
{
var result = new Hitlist();
result.Populate(str);
return result;
}
///
/// Creates a new hitlist.
///
/// The path to the hitlist to read.
public Hitlist(string Filepath)
{
Read(File.Open(Filepath, FileMode.Open, FileAccess.Read, FileShare.Read));
}
}
}