using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.IO; namespace BASeCamp.Configuration { /// /// class used to represent any INI value, section, or comment. /// public abstract class INIItem { public abstract override string ToString(); } public class INIDataItem : INIItem { public String Name { get; set; } public String Value { get; set; } public override string ToString() { return Name + "=" + Value; } public INIDataItem(String pName, String pValue) { Name=pName; Value=pValue; } } public class INIComment : INIItem { public String Comment {get;set;} public INIComment(String pComment) { Comment = pComment; } public override string ToString() { return Comment; } } public class INISection { public List INIItems; public String Name { get; set; } public String eolComment { get; set; } public INISection(String pName,string peolComment,List Values) { Name=pName; INIItems=Values; if (peolComment == null) peolComment = ""; eolComment = peolComment; } public INIDataItem this[String index] { get { INIDataItem returnthis = getValues().FirstOrDefault((w) => w.Name.Equals(index, StringComparison.OrdinalIgnoreCase)); if (returnthis == null) { //returnthis = new INISection(index, null, new List()); returnthis = new INIDataItem(index, ""); INIItems.Add(returnthis); } return returnthis; } set { //remove any existing value with the given name... INIItem itemfound = getValues().FirstOrDefault(w => w.Name.Equals(index, StringComparison.OrdinalIgnoreCase)); if(itemfound!=null) INIItems.Remove(itemfound); INIItems.Add(value); } } public IEnumerable getValues() { foreach(INIItem loopitem in INIItems) { INIDataItem casted = loopitem as INIDataItem; if (casted!=null) yield return casted; } } public override string ToString() { return "[" + Name + "] (" + getValues().Count().ToString() + " Values, " + (INIItems.Count() - getValues().Count()).ToString() + " Comments."; } } public class INIFile { public List Sections{get;set;} public INIFile() { Sections = new List(); } public INIFile(String filename) { LoadINI(filename); } //Indexer... public INISection this[String index] { get { INISection returnthis = Sections.FirstOrDefault((w) => w.Name.Equals(index, StringComparison.OrdinalIgnoreCase)); if (returnthis == null) { returnthis = new INISection(index, "", new List()); Sections.Add(returnthis); } return returnthis; } set { //remove any existing value with the given name... INISection itemfound = Sections.FirstOrDefault(w => w.Name.Equals(index, StringComparison.OrdinalIgnoreCase)); if (itemfound != null) Sections.Remove(itemfound); Sections.Add(value); } } private static INIDataItem ParseINIValue(String valueline) { int equalspos = valueline.IndexOf('='); String valuename="",valuedata=""; if(equalspos==-1) return null; valuename = valueline.Substring(0,equalspos).Trim(); valuedata = valueline.Substring(equalspos + 1).Trim(); return new INIDataItem(valuename,valuedata); } public void LoadINI(String Filename) { using (var newreader = new StreamReader(File.OpenRead(Filename),true)) { LoadINI(newreader); newreader.Close(); } } public void LoadINI(String Filename, Encoding pEncoding) { using (var newreader = new StreamReader(File.OpenRead(Filename),pEncoding)) { LoadINI(newreader); newreader.Close(); } } public void LoadINI(StreamReader fromstream) { String currentline=null; Sections = new List(); INISection globalsection = new INISection("cINIFilecsGlobals", "", new List()); INISection currentSection = globalsection; //while there is still text to read. while ((currentline = fromstream.ReadLine()) != null) { //trim the read in line... currentline = currentline.Trim(); //if it starts with a square bracket, it's a section. if (currentline.StartsWith("[")) { //parse out the section name... String newsectionname = currentline.Substring(1, currentline.IndexOf(']') - 1); String eolComment = ""; if (currentline.IndexOf(';') > -1) eolComment = currentline.Substring(currentline.IndexOf(';')); currentSection = new INISection(newsectionname, eolComment, new List()); Sections.Add(currentSection); } else if (currentline.StartsWith(";")) { //add a new Comment INIItem to the current section. INIItem newitem = new INIComment(currentline); currentSection.INIItems.Add(newitem); } else { INIDataItem createitem = ParseINIValue(currentline); if (createitem != null) currentSection.INIItems.Add(createitem); } } if (globalsection.INIItems.Count() > 0) Sections.Add(globalsection); } public void SaveINI(String filename) { using (StreamWriter swriter = new StreamWriter(File.OpenWrite(filename),Encoding.ASCII)) { SaveINI(swriter); swriter.Close(); } } public void SaveINI(String filename, Encoding pEncoding) { using (StreamWriter swriter = new StreamWriter(File.OpenWrite(filename),pEncoding)) { SaveINI(swriter); swriter.Close(); } } public void SaveINI(StreamWriter tostream) { //save to the given stream. foreach (INISection loopsection in Sections) { //don't write out "[global]" for the global section, if present. if(!loopsection.Name.Equals("cINIFilecsGlobals",StringComparison.OrdinalIgnoreCase)) { tostream.Write("[" + loopsection.Name + "]"); if (loopsection.eolComment.Length > 0) tostream.WriteLine(" " + loopsection.eolComment); else tostream.WriteLine(); } foreach(INIItem itemloop in loopsection.INIItems) { tostream.WriteLine(itemloop.ToString()); } } } } }