1: /*
2: Copyright (c) 2010 <a href="http://www.gutgames.com">James Craig</a>
3:
4: Permission is hereby granted, free of charge, to any person obtaining a copy
5: of this software and associated documentation files (the "Software"), to deal
6: in the Software without restriction, including without limitation the rights
7: to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8: copies of the Software, and to permit persons to whom the Software is
9: furnished to do so, subject to the following conditions:
10:
11: The above copyright notice and this permission notice shall be included in
12: all copies or substantial portions of the Software.
13:
14: THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15: IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16: FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17: AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18: LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19: OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
20: THE SOFTWARE.*/
21:
22: #region Usings
23: using System;
24: using System.Collections.Generic;
25: using System.Linq;
26: using System.Text;
27: using System.Text.RegularExpressions;
28: using Utilities.IO;
29:
30: #endregion
31:
32: namespace Utilities.FileFormats.INI
33: {
34: /// <summary>
35: /// Class for helping with INI files
36: /// </summary>
37: public class INI
38: {
39: #region Constructor
40: /// <summary>
41: /// Constructor
42: /// </summary>
43: public INI()
44: {
45: LoadFile();
46: }
47:
48: /// <summary>
49: /// Constructor
50: /// </summary>
51: /// <param name="FileName">Name of the file</param>
52: public INI(string FileName)
53: {
54: this.FileName = FileName;
55: LoadFile();
56: }
57: #endregion
58:
59: #region Public Functions
60: /// <summary>
61: /// Writes a change to an INI file
62: /// </summary>
63: /// <param name="Section">Section</param>
64: /// <param name="Key">Key</param>
65: /// <param name="Value">Value</param>
66: public void WriteToINI(string Section, string Key, string Value)
67: {
68: if (_FileContents.Keys.Contains(Section))
69: {
70: if (_FileContents[Section].Keys.Contains(Key))
71: {
72: _FileContents[Section][Key] = Value;
73: }
74: else
75: {
76: _FileContents[Section].Add(Key, Value);
77: }
78: }
79: else
80: {
81: Dictionary<string, string> TempDictionary = new Dictionary<string, string>();
82: TempDictionary.Add(Key, Value);
83: _FileContents.Add(Section, TempDictionary);
84: }
85: WriteFile();
86: }
87:
88: /// <summary>
89: /// Reads a value from an INI file
90: /// </summary>
91: /// <param name="Section">Section</param>
92: /// <param name="Key">Key</param>
93: /// <param name="DefaultValue">Default value if it does not exist</param>
94: public string ReadFromINI(string Section, string Key, string DefaultValue)
95: {
96: if (_FileContents.Keys.Contains(Section))
97: {
98: if (_FileContents[Section].Keys.Contains(Key))
99: {
100: return _FileContents[Section][Key];
101: }
102: }
103: return DefaultValue;
104: }
105:
106: /// <summary>
107: /// Returns an XML representation of the INI file
108: /// </summary>
109: /// <returns>An XML representation of the INI file</returns>
110: public string ToXML()
111: {
112: if (string.IsNullOrEmpty(this.FileName))
113: return "<?xml version=\"1.0\" encoding=\"utf-8\"?>\r\n<INI>\r\n</INI>";
114: StringBuilder Builder = new StringBuilder();
115: Builder.Append("<?xml version=\"1.0\" encoding=\"utf-8\"?>\r\n");
116: Builder.Append("<INI>\r\n");
117: foreach (string Header in _FileContents.Keys)
118: {
119: Builder.Append("<section name=\"" + Header + "\">\r\n");
120: foreach (string Key in _FileContents[Header].Keys)
121: {
122: Builder.Append("<key name=\"" + Key + "\">" + _FileContents[Header][Key] + "</key>\r\n");
123: }
124: Builder.Append("</section>\r\n");
125: }
126: Builder.Append("</INI>");
127: return Builder.ToString();
128: }
129: #endregion
130:
131: #region Private Functions
132: /// <summary>
133: /// Writes the INI information to a file
134: /// </summary>
135: private void WriteFile()
136: {
137: if (string.IsNullOrEmpty(this.FileName))
138: return;
139: StringBuilder Builder = new StringBuilder();
140: foreach (string Header in _FileContents.Keys)
141: {
142: Builder.Append("[" + Header + "]\r\n");
143: foreach (string Key in _FileContents[Header].Keys)
144: {
145: Builder.Append(Key + "=" + _FileContents[Header][Key] + "\r\n");
146: }
147: }
148: FileManager.SaveFile(Builder.ToString(), FileName);
149: }
150:
151: /// <summary>
152: /// Loads an INI file
153: /// </summary>
154: private void LoadFile()
155: {
156: _FileContents = new Dictionary<string, Dictionary<string, string>>();
157: if (string.IsNullOrEmpty(this.FileName))
158: return;
159:
160: string Contents = FileManager.GetFileContents(FileName);
161: Regex Section = new Regex("[" + Regex.Escape(" ") + "\t]*" + Regex.Escape("[") + ".*" + Regex.Escape("]\r\n"));
162: string[] Sections = Section.Split(Contents);
163: MatchCollection SectionHeaders = Section.Matches(Contents);
164: int Counter = 1;
165: foreach (Match SectionHeader in SectionHeaders)
166: {
167: string[] Splitter = { "\r\n" };
168: string[] Splitter2 = { "=" };
169: string[] Items = Sections[Counter].Split(Splitter, StringSplitOptions.RemoveEmptyEntries);
170: Dictionary<string, string> SectionValues = new Dictionary<string, string>();
171: foreach (string Item in Items)
172: {
173: SectionValues.Add(Item.Split(Splitter2, StringSplitOptions.None)[0], Item.Split(Splitter2, StringSplitOptions.None)[1]);
174: }
175: _FileContents.Add(SectionHeader.Value.Replace("[", "").Replace("]\r\n", ""), SectionValues);
176: ++Counter;
177: }
178: }
179:
180: #endregion
181:
182: #region Properties
183: /// <summary>
184: /// Name of the file
185: /// </summary>
186: public string FileName
187: {
188: get { return _FileName; }
189: set { _FileName = value; LoadFile(); }
190: }
191:
192: private Dictionary<string, Dictionary<string, string>> FileContents
193: {
194: get { return _FileContents; }
195: set { _FileContents = value; }
196: }
197: private string _FileName = string.Empty;
198: private Dictionary<string, Dictionary<string, string>> _FileContents = null;
199: #endregion
200: }
201: }