using System; using System.Collections.Generic; using System.IO; using System.Text; using System.Text.RegularExpressions; using IniParser; using IniParser.Exceptions; using IniParser.Model; using IniParser.Model.Configuration; using IniParser.Parser; using Wabbajack.Paths; namespace Wabbajack.Installer; public static class IniExtensions { private static IniDataParser IniParser() { var config = new IniParserConfiguration {AllowDuplicateKeys = true, AllowDuplicateSections = true}; var parser = new IniDataParser(config); return parser; } /// /// Loads INI data from the given filename and returns a dynamic type that /// can use . operators to navigate the INI. /// /// /// public static IniData LoadIniFile(this AbsolutePath file) { return new FileIniDataParser(IniParser()).ReadFile(file.ToString()); } public static void SaveIniFile(this IniData data, AbsolutePath file) { var parser = new FileIniDataParser(IniParser()); parser.WriteFile(file.ToString(), data); } /// /// Loads a INI from the given string /// /// /// public static IniData LoadIniString(this string file) { return new FileIniDataParser(IniParser()).ReadData( new StreamReader(new MemoryStream(Encoding.UTF8.GetBytes(file)))); } public static string FromMO2Ini(this string s) { if (string.IsNullOrEmpty(s)) return s; if (s.StartsWith("@ByteArray(") && s.EndsWith(")")) return UnescapeUTF8(s.Substring("@ByteArray(".Length, s.Length - "@ByteArray(".Length - ")".Length)); return UnescapeString(s); } private static string UnescapeString(string s) { if (s.Trim().StartsWith("\"") || s.Contains("\\\\")) return Regex.Unescape(s.Trim('"')); return s; } private static string UnescapeUTF8(string s) { var acc = new List(); for (var i = 0; i < s.Length; i++) { var c = s[i]; switch (c) { case '\\': i++; var nc = s[i]; switch (nc) { case '\\': acc.Add((byte) '\\'); break; case 'x': var chrs = s[i + 1] + s[i + 2].ToString(); i += 2; acc.Add(Convert.ToByte(chrs, 16)); break; default: throw new ParsingException($"Not a valid escape characer {nc}"); } break; default: acc.Add((byte) c); break; } } return Encoding.UTF8.GetString(acc.ToArray()); } }