//****************************************************************************************************** // IniFile.cs - Gbtc // // Copyright © 2015, Grid Protection Alliance. All Rights Reserved. // // Licensed to the Grid Protection Alliance (GPA) under one or more contributor license agreements. See // the NOTICE file distributed with this work for additional information regarding copyright ownership. // The GPA licenses this file to you under the MIT License (MIT), the "License"; you may not use this // file except in compliance with the License. You may obtain a copy of the License at: // // http://www.opensource.org/licenses/MIT // // Unless agreed to in writing, the subject software distributed under the License is distributed on an // "AS-IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. Refer to the // License for the specific language governing permissions and limitations. // // Code Modification History: // ---------------------------------------------------------------------------------------------------- // 01/14/2012 - J. Ritchie Carroll // Generated original version of source code. // //****************************************************************************************************** using System; using System.Collections.Concurrent; using System.Collections.Generic; using System.IO; // ReSharper disable once CheckNamespace public class IniFile { #region [ Members ] // Fields private readonly string m_fileName; private readonly ConcurrentDictionary> m_iniData; #endregion #region [ Constructors ] public IniFile(string fileName) { if ((object)fileName == null) throw new ArgumentNullException("fileName"); m_fileName = fileName; m_iniData = new ConcurrentDictionary>(StringComparer.CurrentCultureIgnoreCase); Load(); } #endregion #region [ Properties ] public string this[string sectionName, string entryName] { get { ConcurrentDictionary section = m_iniData.GetOrAdd(sectionName, CreateNewSection); return section.GetOrAdd(entryName, (string)null); } set { ConcurrentDictionary section = m_iniData.GetOrAdd(sectionName, CreateNewSection); section[entryName] = value; } } public string this[string sectionName, string entryName, string defaultValue] { get { ConcurrentDictionary section = m_iniData.GetOrAdd(sectionName, CreateNewSection); return section.GetOrAdd(entryName, defaultValue); } } #endregion #region [ Methods ] public void Load() { if (!File.Exists(m_fileName)) return; using (StreamReader reader = new StreamReader(m_fileName)) { string line = reader.ReadLine(); ConcurrentDictionary section = null; while ((object)line != null) { line = RemoveComments(line); if (line.Length > 0) { // Check for new section int startBracketIndex = line.IndexOf('['); if (startBracketIndex == 0) { int endBracketIndex = line.IndexOf(']'); if (endBracketIndex > 1) { string sectionName = line.Substring(startBracketIndex + 1, endBracketIndex - 1); if (!string.IsNullOrEmpty(sectionName)) section = m_iniData.GetOrAdd(sectionName, CreateNewSection); } } if ((object)section == null) throw new InvalidOperationException("INI file did not begin with a [section]"); // Check for key/value pair int equalsIndex = line.IndexOf("="); if (equalsIndex > 0) { string key = line.Substring(0, equalsIndex).Trim(); if (!string.IsNullOrEmpty(key)) section[key] = line.Substring(equalsIndex + 1).Trim(); } } line = reader.ReadLine(); } } } // Saving INI file will strip comments - sorry :-( public void Save() { Save(m_fileName); } public void Save(string fileName) { if ((object)fileName == null) throw new ArgumentNullException("fileName"); using (StreamWriter writer = new StreamWriter(fileName)) { foreach (KeyValuePair> section in m_iniData) { writer.WriteLine("[{0}]", section.Key); foreach (KeyValuePair entry in section.Value) { writer.WriteLine("{0} = {1}", entry.Key, entry.Value); } writer.WriteLine(); } } } private ConcurrentDictionary CreateNewSection(string sectionName) { return new ConcurrentDictionary(StringComparer.InvariantCultureIgnoreCase); } #endregion #region [ Static ] // Static Methods // Remove any comments from key value string private static string RemoveComments(string keyValue) { // Remove any trailing comments from key value keyValue = keyValue.Trim(); int commentIndex = keyValue.LastIndexOf(';'); if (commentIndex > -1) keyValue = keyValue.Substring(0, commentIndex).Trim(); return keyValue; } #endregion }