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)); } } }