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());
}
}
}
}
}