using System; using System.IO; using System.Text; using Config.Net.Core; using Config.Net.Stores.Formats.Ini; namespace Config.Net.Stores { /// /// Simple INI storage. /// class IniFileConfigStore : IConfigStore { private readonly string? _fullName; private readonly StructuredIniFile _iniFile; /// /// /// r /// File does not have to exist, however it will be created as soon as you /// try to write to it public IniFileConfigStore(string name, bool isFilePath, bool parseInlineComments, bool unescapeNewLines = false) { if (name == null) throw new ArgumentNullException(nameof(name)); if (isFilePath) { _fullName = Path.GetFullPath(name); // Allow relative path to INI file string? parentDirPath = Path.GetDirectoryName(_fullName); if (string.IsNullOrEmpty(parentDirPath)) throw new IOException("the provided directory path is not valid"); if (!Directory.Exists(parentDirPath)) { Directory.CreateDirectory(parentDirPath); } _iniFile = ReadIniFile(_fullName, parseInlineComments, unescapeNewLines); CanWrite = true; } else { _iniFile = ReadIniContent(name, parseInlineComments, unescapeNewLines); CanWrite = false; } CanRead = true; } public string Name => ".ini"; public bool CanRead { get; } public bool CanWrite { get; } public string? Read(string key) { if (FlatArrays.IsArrayLength(key, k => _iniFile[k], out int length)) { return length.ToString(); } if (FlatArrays.IsArrayElement(key, k => _iniFile[k], out string? element)) { return element; } return _iniFile[key]; } public void Write(string key, string? value) { if (!CanWrite) return; _iniFile[key] = value; WriteIniFile(); } private static StructuredIniFile ReadIniFile(string fullName, bool parseInlineComments, bool unescapeNewLines = false) { FileInfo iniFile = new FileInfo(fullName); if(iniFile.Exists) { using(FileStream stream = iniFile.Open(FileMode.Open, FileAccess.Read, FileShare.ReadWrite)) { return StructuredIniFile.ReadFrom(stream, parseInlineComments, unescapeNewLines); } } else { return new StructuredIniFile(); } } private static StructuredIniFile ReadIniContent(string content, bool parseInlineComments, bool unescapeNewLines = false) { using (Stream input = new MemoryStream(Encoding.UTF8.GetBytes(content))) { return StructuredIniFile.ReadFrom(input, parseInlineComments, unescapeNewLines); } } private void WriteIniFile() { if (_fullName == null) return; using(FileStream stream = File.Create(_fullName)) { _iniFile.WriteTo(stream); } } public void Dispose() { //nothing to dispose } } }