namespace RioJoy.Core.Profiles;
///
/// Minimal INI reader (sections, key = value, ;/# comments)
/// sufficient to parse the legacy RIO.ini. Keys are case-insensitive.
///
public sealed class IniFile
{
private readonly Dictionary> _sections =
new(StringComparer.OrdinalIgnoreCase);
public static IniFile Parse(string text)
{
if (text is null) throw new ArgumentNullException(nameof(text));
var ini = new IniFile();
var current = new Dictionary(StringComparer.OrdinalIgnoreCase);
ini._sections[string.Empty] = current;
foreach (string rawLine in text.Split('\n'))
{
string line = rawLine.Trim();
if (line.Length == 0 || line[0] is ';' or '#')
continue;
if (line[0] == '[' && line[^1] == ']')
{
string section = line[1..^1].Trim();
if (!ini._sections.TryGetValue(section, out current!))
ini._sections[section] = current = new Dictionary(StringComparer.OrdinalIgnoreCase);
continue;
}
int eq = line.IndexOf('=');
if (eq < 0)
continue;
string key = line[..eq].Trim();
string value = line[(eq + 1)..].Trim();
if (key.Length > 0)
current[key] = value;
}
return ini;
}
/// All key/value pairs in a section (empty if the section is absent).
public IDictionary Section(string name) =>
_sections.TryGetValue(name, out Dictionary? s)
? s
: new Dictionary();
public string? GetString(string section, string key) =>
Section(section).TryGetValue(key, out string? v) ? v : null;
public bool GetBool(string section, string key, bool fallback)
{
string? v = GetString(section, key);
if (v is null)
return fallback;
return v.Trim().ToLowerInvariant() switch
{
"1" or "true" or "yes" or "on" => true,
"0" or "false" or "no" or "off" => false,
_ => fallback,
};
}
/// Parse an integer value that may be hex (0x…) or decimal.
public static int ParseInt(string value)
{
if (value is null) throw new ArgumentNullException(nameof(value));
string v = value.Trim();
bool neg = v.StartsWith("-", StringComparison.Ordinal);
if (neg) v = v[1..];
int magnitude = v.StartsWith("0x", StringComparison.OrdinalIgnoreCase)
? Convert.ToInt32(v[2..], 16)
: int.Parse(v);
return neg ? -magnitude : magnitude;
}
}