using System.Text.RegularExpressions;
namespace GsaEditor.Core.IO;
///
/// Represents a single entry parsed from a .idx NML index file.
///
public class GsaIndexEntry
{
///
/// The file alias (relative path) of the entry.
///
public string Id { get; set; } = string.Empty;
///
/// Compression method: 0 = raw, 1 = zlib.
///
public int Method { get; set; }
///
/// Original (decompressed) size in bytes.
///
public uint Length { get; set; }
///
/// Compressed size in bytes.
///
public uint CompressedLength { get; set; }
///
/// Byte offset of the data block within the archive.
///
public long Offset { get; set; }
}
///
/// Parses .idx NML index files into a list of .
/// NML is the engine's own tag syntax (<Name=value> blocks, see ),
/// not standard XML.
///
public static class GsaIndexReader
{
private static readonly Regex EntryRegex = new(
@".*?)\n\s*>",
RegexOptions.Singleline | RegexOptions.Compiled);
private static readonly Regex TagRegex = new(
@"<(?\w+)=""?(?[^"">]*)""?>",
RegexOptions.Compiled);
///
/// Reads index entries from the specified .idx file.
///
/// The path to the .idx file.
/// A list of parsed index entries.
public static List Read(string filePath)
{
var text = File.ReadAllText(filePath);
var entries = new List();
foreach (Match entryMatch in EntryRegex.Matches(text))
{
var entry = new GsaIndexEntry();
foreach (Match tag in TagRegex.Matches(entryMatch.Groups["body"].Value))
{
var value = tag.Groups["value"].Value;
switch (tag.Groups["name"].Value)
{
case "ID":
entry.Id = value;
break;
case "Method":
entry.Method = value.Equals("Zlib", StringComparison.OrdinalIgnoreCase) ? 1 : 0;
break;
case "Len":
entry.Length = uint.TryParse(value, out var l) ? l : 0;
break;
case "CompLen":
entry.CompressedLength = uint.TryParse(value, out var cl) ? cl : 0;
break;
case "Offset":
entry.Offset = long.TryParse(value, out var o) ? o : 0;
break;
}
}
entries.Add(entry);
}
return entries;
}
}