git-svn-id: http://libopenmetaverse.googlecode.com/svn/trunk@2318 52acb1d6-8a22-11de-b505-999d5b087335
329 lines
8.5 KiB
C#
329 lines
8.5 KiB
C#
#region Copyright
|
|
//
|
|
// Nini Configuration Project.
|
|
// Copyright (C) 2006 Brent R. Matzelle. All rights reserved.
|
|
//
|
|
// This software is published under the terms of the MIT X11 license, a copy of
|
|
// which has been included with this distribution in the LICENSE.txt file.
|
|
//
|
|
#endregion
|
|
|
|
using System;
|
|
using System.IO;
|
|
using System.Collections;
|
|
using ExtensionLoader.Ini;
|
|
|
|
namespace ExtensionLoader.Config
|
|
{
|
|
/// <include file='IniConfigSource.xml' path='//Class[@name="IniConfigSource"]/docs/*' />
|
|
public class IniConfigSource : ConfigSourceBase
|
|
{
|
|
#region Private variables
|
|
IniDocument iniDocument = null;
|
|
string savePath = null;
|
|
bool caseSensitive = true;
|
|
#endregion
|
|
|
|
#region Public properties
|
|
#endregion
|
|
|
|
#region Constructors
|
|
/// <include file='IniConfigSource.xml' path='//Constructor[@name="Constructor"]/docs/*' />
|
|
public IniConfigSource ()
|
|
{
|
|
iniDocument = new IniDocument ();
|
|
}
|
|
|
|
/// <include file='IniConfigSource.xml' path='//Constructor[@name="ConstructorPath"]/docs/*' />
|
|
public IniConfigSource (string filePath)
|
|
{
|
|
Load (filePath);
|
|
}
|
|
|
|
/// <include file='IniConfigSource.xml' path='//Constructor[@name="ConstructorTextReader"]/docs/*' />
|
|
public IniConfigSource (TextReader reader)
|
|
{
|
|
Load (reader);
|
|
}
|
|
|
|
/// <include file='IniConfigSource.xml' path='//Constructor[@name="ConstructorIniDocument"]/docs/*' />
|
|
public IniConfigSource (IniDocument document)
|
|
{
|
|
Load (document);
|
|
}
|
|
|
|
/// <include file='IniConfigSource.xml' path='//Constructor[@name="ConstructorStream"]/docs/*' />
|
|
public IniConfigSource (Stream stream)
|
|
{
|
|
Load (stream);
|
|
}
|
|
#endregion
|
|
|
|
#region Public properties
|
|
/// <include file='IniConfigSource.xml' path='//Property[@name="CaseSensitive"]/docs/*' />
|
|
public bool CaseSensitive
|
|
{
|
|
get { return caseSensitive; }
|
|
set { caseSensitive = value; }
|
|
}
|
|
|
|
/// <include file='IniConfigSource.xml' path='//Property[@name="SavePath"]/docs/*' />
|
|
public string SavePath
|
|
{
|
|
get { return savePath; }
|
|
}
|
|
#endregion
|
|
|
|
#region Public methods
|
|
/// <include file='IniConfigSource.xml' path='//Method[@name="LoadPath"]/docs/*' />
|
|
public void Load (string filePath)
|
|
{
|
|
Load (new StreamReader (filePath));
|
|
this.savePath = filePath;
|
|
}
|
|
|
|
/// <include file='IniConfigSource.xml' path='//Method[@name="LoadTextReader"]/docs/*' />
|
|
public void Load (TextReader reader)
|
|
{
|
|
Load (new IniDocument (reader));
|
|
}
|
|
|
|
/// <include file='IniConfigSource.xml' path='//Method[@name="LoadIniDocument"]/docs/*' />
|
|
public void Load (IniDocument document)
|
|
{
|
|
this.Configs.Clear ();
|
|
|
|
this.Merge (this); // required for SaveAll
|
|
iniDocument = document;
|
|
Load ();
|
|
}
|
|
|
|
/// <include file='IniConfigSource.xml' path='//Method[@name="LoadStream"]/docs/*' />
|
|
public void Load (Stream stream)
|
|
{
|
|
Load (new StreamReader (stream));
|
|
}
|
|
|
|
/// <include file='IniConfigSource.xml' path='//Method[@name="Save"]/docs/*' />
|
|
public override void Save ()
|
|
{
|
|
if (!IsSavable ()) {
|
|
throw new ArgumentException ("Source cannot be saved in this state");
|
|
}
|
|
|
|
MergeConfigsIntoDocument ();
|
|
|
|
iniDocument.Save (this.savePath);
|
|
base.Save ();
|
|
}
|
|
|
|
/// <include file='IniConfigSource.xml' path='//Method[@name="SavePath"]/docs/*' />
|
|
public void Save (string path)
|
|
{
|
|
this.savePath = path;
|
|
this.Save ();
|
|
}
|
|
|
|
/// <include file='IniConfigSource.xml' path='//Method[@name="SaveTextWriter"]/docs/*' />
|
|
public void Save (TextWriter writer)
|
|
{
|
|
MergeConfigsIntoDocument ();
|
|
iniDocument.Save (writer);
|
|
savePath = null;
|
|
OnSaved (new EventArgs ());
|
|
}
|
|
|
|
/// <include file='IniConfigSource.xml' path='//Method[@name="SaveStream"]/docs/*' />
|
|
public void Save (Stream stream)
|
|
{
|
|
MergeConfigsIntoDocument ();
|
|
iniDocument.Save (stream);
|
|
savePath = null;
|
|
OnSaved (new EventArgs ());
|
|
}
|
|
|
|
/// <include file='IConfigSource.xml' path='//Method[@name="Reload"]/docs/*' />
|
|
public override void Reload ()
|
|
{
|
|
if (savePath == null) {
|
|
throw new ArgumentException ("Error reloading: You must have "
|
|
+ "the loaded the source from a file");
|
|
}
|
|
|
|
iniDocument = new IniDocument (savePath);
|
|
MergeDocumentIntoConfigs ();
|
|
base.Reload ();
|
|
}
|
|
|
|
/// <include file='IniConfigSource.xml' path='//Method[@name="ToString"]/docs/*' />
|
|
public override string ToString ()
|
|
{
|
|
MergeConfigsIntoDocument ();
|
|
StringWriter writer = new StringWriter ();
|
|
iniDocument.Save (writer);
|
|
|
|
return writer.ToString ();
|
|
}
|
|
#endregion
|
|
|
|
#region Private methods
|
|
/// <summary>
|
|
/// Merges all of the configs from the config collection into the
|
|
/// IniDocument before it is saved.
|
|
/// </summary>
|
|
private void MergeConfigsIntoDocument ()
|
|
{
|
|
RemoveSections ();
|
|
foreach (IConfig config in this.Configs)
|
|
{
|
|
string[] keys = config.GetKeys ();
|
|
|
|
// Create a new section if one doesn't exist
|
|
if (iniDocument.Sections[config.Name] == null) {
|
|
IniSection section = new IniSection (config.Name);
|
|
iniDocument.Sections.Add (section);
|
|
}
|
|
RemoveKeys (config.Name);
|
|
|
|
for (int i = 0; i < keys.Length; i++)
|
|
{
|
|
iniDocument.Sections[config.Name].Set (keys[i], config.Get (keys[i]));
|
|
}
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Removes all INI sections that were removed as configs.
|
|
/// </summary>
|
|
private void RemoveSections ()
|
|
{
|
|
IniSection section = null;
|
|
for (int i = 0; i < iniDocument.Sections.Count; i++)
|
|
{
|
|
section = iniDocument.Sections[i];
|
|
if (this.Configs[section.Name] == null) {
|
|
iniDocument.Sections.Remove (section.Name);
|
|
}
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Removes all INI keys that were removed as config keys.
|
|
/// </summary>
|
|
private void RemoveKeys (string sectionName)
|
|
{
|
|
IniSection section = iniDocument.Sections[sectionName];
|
|
|
|
if (section != null) {
|
|
foreach (string key in section.GetKeys ())
|
|
{
|
|
if (this.Configs[sectionName].Get (key) == null) {
|
|
section.Remove (key);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Loads the configuration file.
|
|
/// </summary>
|
|
private void Load ()
|
|
{
|
|
IniConfig config = null;
|
|
IniSection section = null;
|
|
IniItem item = null;
|
|
|
|
for (int j = 0; j < iniDocument.Sections.Count; j++)
|
|
{
|
|
section = iniDocument.Sections[j];
|
|
config = new IniConfig (section.Name, this);
|
|
|
|
for (int i = 0; i < section.ItemCount; i++)
|
|
{
|
|
item = section.GetItem (i);
|
|
|
|
if (item.Type == IniType.Key) {
|
|
config.Add (item.Name, item.Value);
|
|
}
|
|
}
|
|
|
|
this.Configs.Add (config);
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Merges the IniDocument into the Configs when the document is
|
|
/// reloaded.
|
|
/// </summary>
|
|
private void MergeDocumentIntoConfigs ()
|
|
{
|
|
// Remove all missing configs first
|
|
RemoveConfigs ();
|
|
|
|
IniSection section = null;
|
|
for (int i = 0; i < iniDocument.Sections.Count; i++)
|
|
{
|
|
section = iniDocument.Sections[i];
|
|
|
|
IConfig config = this.Configs[section.Name];
|
|
if (config == null) {
|
|
// The section is new so add it
|
|
config = new ConfigBase (section.Name, this);
|
|
this.Configs.Add (config);
|
|
}
|
|
RemoveConfigKeys (config);
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Removes all configs that are not in the newly loaded INI doc.
|
|
/// </summary>
|
|
private void RemoveConfigs ()
|
|
{
|
|
IConfig config = null;
|
|
for (int i = this.Configs.Count - 1; i > -1; i--)
|
|
{
|
|
config = this.Configs[i];
|
|
// If the section is not present in the INI doc
|
|
if (iniDocument.Sections[config.Name] == null) {
|
|
this.Configs.Remove (config);
|
|
}
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Removes all INI keys that were removed as config keys.
|
|
/// </summary>
|
|
private void RemoveConfigKeys (IConfig config)
|
|
{
|
|
IniSection section = iniDocument.Sections[config.Name];
|
|
|
|
// Remove old keys
|
|
string[] configKeys = config.GetKeys ();
|
|
foreach (string configKey in configKeys)
|
|
{
|
|
if (!section.Contains (configKey)) {
|
|
// Key doesn't exist, remove
|
|
config.Remove (configKey);
|
|
}
|
|
}
|
|
|
|
// Add or set all new keys
|
|
string[] keys = section.GetKeys ();
|
|
for (int i = 0; i < keys.Length; i++)
|
|
{
|
|
string key = keys[i];
|
|
config.Set (key, section.GetItem (i).Value);
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Returns true if this instance is savable.
|
|
/// </summary>
|
|
private bool IsSavable ()
|
|
{
|
|
return (this.savePath != null);
|
|
}
|
|
#endregion
|
|
}
|
|
} |