Importing Nini's .ini file parsing into ExtensionLoader
git-svn-id: http://libopenmetaverse.googlecode.com/svn/trunk@2318 52acb1d6-8a22-11de-b505-999d5b087335
This commit is contained in:
147
ExtensionLoader/Config/AliasText.cs
Normal file
147
ExtensionLoader/Config/AliasText.cs
Normal file
@@ -0,0 +1,147 @@
|
||||
#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.Collections;
|
||||
|
||||
namespace ExtensionLoader.Config
|
||||
{
|
||||
/// <include file='AliasText.xml' path='//Class[@name="AliasText"]/docs/*' />
|
||||
public class AliasText
|
||||
{
|
||||
#region Private variables
|
||||
Hashtable intAlias = null;
|
||||
Hashtable booleanAlias = null;
|
||||
#endregion
|
||||
|
||||
#region Constructors
|
||||
/// <include file='AliasText.xml' path='//Constructor[@name="AliasText"]/docs/*' />
|
||||
public AliasText ()
|
||||
{
|
||||
intAlias = InsensitiveHashtable ();
|
||||
booleanAlias = InsensitiveHashtable ();
|
||||
DefaultAliasLoad ();
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region Public methods
|
||||
/// <include file='AliasText.xml' path='//Method[@name="AddAliasInt"]/docs/*' />
|
||||
public void AddAlias (string key, string alias, int value)
|
||||
{
|
||||
if (intAlias.Contains (key)) {
|
||||
Hashtable keys = (Hashtable)intAlias[key];
|
||||
|
||||
keys[alias] = value;
|
||||
} else {
|
||||
Hashtable keys = InsensitiveHashtable ();
|
||||
keys[alias] = value;
|
||||
intAlias.Add (key, keys);
|
||||
}
|
||||
}
|
||||
|
||||
/// <include file='AliasText.xml' path='//Method[@name="AddAliasBoolean"]/docs/*' />
|
||||
public void AddAlias (string alias, bool value)
|
||||
{
|
||||
booleanAlias[alias] = value;
|
||||
}
|
||||
|
||||
#if (NET_COMPACT_1_0)
|
||||
#else
|
||||
/// <include file='AliasText.xml' path='//Method[@name="AddAliasEnum"]/docs/*' />
|
||||
public void AddAlias (string key, Enum enumAlias)
|
||||
{
|
||||
SetAliasTypes (key, enumAlias);
|
||||
}
|
||||
#endif
|
||||
|
||||
/// <include file='AliasText.xml' path='//Method[@name="ContainsBoolean"]/docs/*' />
|
||||
public bool ContainsBoolean (string key)
|
||||
{
|
||||
return booleanAlias.Contains (key);
|
||||
}
|
||||
|
||||
/// <include file='AliasText.xml' path='//Method[@name="ContainsInt"]/docs/*' />
|
||||
public bool ContainsInt (string key, string alias)
|
||||
{
|
||||
bool result = false;
|
||||
|
||||
if (intAlias.Contains (key)) {
|
||||
Hashtable keys = (Hashtable)intAlias[key];
|
||||
result = (keys.Contains (alias));
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/// <include file='AliasText.xml' path='//Method[@name="GetBoolean"]/docs/*' />
|
||||
public bool GetBoolean (string key)
|
||||
{
|
||||
if (!booleanAlias.Contains (key)) {
|
||||
throw new ArgumentException ("Alias does not exist for text");
|
||||
}
|
||||
|
||||
return (bool)booleanAlias[key];
|
||||
}
|
||||
|
||||
/// <include file='AliasText.xml' path='//Method[@name="GetInt"]/docs/*' />
|
||||
public int GetInt (string key, string alias)
|
||||
{
|
||||
if (!intAlias.Contains (key)) {
|
||||
throw new ArgumentException ("Alias does not exist for key");
|
||||
}
|
||||
|
||||
Hashtable keys = (Hashtable)intAlias[key];
|
||||
|
||||
if (!keys.Contains (alias)) {
|
||||
throw new ArgumentException ("Config value does not match a " +
|
||||
"supplied alias");
|
||||
}
|
||||
|
||||
return (int)keys[alias];
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region Private methods
|
||||
/// <summary>
|
||||
/// Loads the default alias values.
|
||||
/// </summary>
|
||||
private void DefaultAliasLoad ()
|
||||
{
|
||||
AddAlias("true", true);
|
||||
AddAlias("false", false);
|
||||
}
|
||||
|
||||
#if (NET_COMPACT_1_0)
|
||||
#else
|
||||
/// <summary>
|
||||
/// Extracts and sets the alias types from an enumeration.
|
||||
/// </summary>
|
||||
private void SetAliasTypes (string key, Enum enumAlias)
|
||||
{
|
||||
string[] names = Enum.GetNames (enumAlias.GetType ());
|
||||
int[] values = (int[])Enum.GetValues (enumAlias.GetType ());
|
||||
|
||||
for (int i = 0; i < names.Length; i++)
|
||||
{
|
||||
AddAlias (key, names[i], values[i]);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
/// <summary>
|
||||
/// Returns a case insensitive hashtable.
|
||||
/// </summary>
|
||||
private Hashtable InsensitiveHashtable ()
|
||||
{
|
||||
return new Hashtable (StringComparer.OrdinalIgnoreCase);
|
||||
}
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
422
ExtensionLoader/Config/ConfigBase.cs
Normal file
422
ExtensionLoader/Config/ConfigBase.cs
Normal file
@@ -0,0 +1,422 @@
|
||||
#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.Collections;
|
||||
using System.Globalization;
|
||||
using ExtensionLoader.Util;
|
||||
|
||||
namespace ExtensionLoader.Config
|
||||
{
|
||||
#region ConfigKeyEventArgs class
|
||||
/// <include file='ConfigKeyEventArgs.xml' path='//Delegate[@name="ConfigKeyEventHandler"]/docs/*' />
|
||||
public delegate void ConfigKeyEventHandler (object sender, ConfigKeyEventArgs e);
|
||||
|
||||
/// <include file='ConfigEventArgs.xml' path='//Class[@name="ConfigEventArgs"]/docs/*' />
|
||||
public class ConfigKeyEventArgs : EventArgs
|
||||
{
|
||||
string keyName = null;
|
||||
string keyValue = null;
|
||||
|
||||
/// <include file='ConfigEventArgs.xml' path='//Constructor[@name="Constructor"]/docs/*' />
|
||||
public ConfigKeyEventArgs (string keyName, string keyValue)
|
||||
{
|
||||
this.keyName = keyName;
|
||||
this.keyValue = keyValue;
|
||||
}
|
||||
|
||||
/// <include file='ConfigEventArgs.xml' path='//Property[@name="KeyName"]/docs/*' />
|
||||
public string KeyName
|
||||
{
|
||||
get { return keyName; }
|
||||
}
|
||||
|
||||
/// <include file='ConfigEventArgs.xml' path='//Property[@name="KeyValue"]/docs/*' />
|
||||
public string KeyValue
|
||||
{
|
||||
get { return keyValue; }
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
|
||||
/// <include file='IConfig.xml' path='//Interface[@name="IConfig"]/docs/*' />
|
||||
public class ConfigBase : IConfig
|
||||
{
|
||||
#region Private variables
|
||||
string configName = null;
|
||||
IConfigSource configSource = null;
|
||||
AliasText aliasText = null;
|
||||
IFormatProvider format = NumberFormatInfo.CurrentInfo;
|
||||
#endregion
|
||||
|
||||
#region Protected variables
|
||||
protected OrderedList keys = new OrderedList ();
|
||||
#endregion
|
||||
|
||||
#region Constructors
|
||||
/// <include file='ConfigBase.xml' path='//Constructor[@name="ConfigBase"]/docs/*' />
|
||||
public ConfigBase (string name, IConfigSource source)
|
||||
{
|
||||
configName = name;
|
||||
configSource = source;
|
||||
aliasText = new AliasText ();
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region Public properties
|
||||
/// <include file='IConfig.xml' path='//Property[@name="Name"]/docs/*' />
|
||||
public string Name
|
||||
{
|
||||
get { return configName; }
|
||||
set {
|
||||
if (configName != value) {
|
||||
Rename (value);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <include file='IConfig.xml' path='//Property[@name="ConfigSource"]/docs/*' />
|
||||
public IConfigSource ConfigSource
|
||||
{
|
||||
get { return configSource; }
|
||||
}
|
||||
|
||||
/// <include file='IConfig.xml' path='//Property[@name="Alias"]/docs/*' />
|
||||
public AliasText Alias
|
||||
{
|
||||
get { return aliasText; }
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region Public methods
|
||||
/// <include file='IConfig.xml' path='//Method[@name="Contains"]/docs/*' />
|
||||
public bool Contains (string key)
|
||||
{
|
||||
return (Get (key) != null);
|
||||
}
|
||||
|
||||
/// <include file='IConfig.xml' path='//Method[@name="Get"]/docs/*' />
|
||||
public virtual string Get (string key)
|
||||
{
|
||||
string result = null;
|
||||
|
||||
if (keys.Contains (key)) {
|
||||
result = keys[key].ToString ();
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/// <include file='IConfig.xml' path='//Method[@name="GetDefault"]/docs/*' />
|
||||
public string Get (string key, string defaultValue)
|
||||
{
|
||||
string result = Get (key);
|
||||
|
||||
return (result == null) ? defaultValue : result;
|
||||
}
|
||||
|
||||
/// <include file='IConfig.xml' path='//Method[@name="GetExpanded"]/docs/*' />
|
||||
public string GetExpanded (string key)
|
||||
{
|
||||
return this.ConfigSource.GetExpanded(this, key);
|
||||
}
|
||||
|
||||
/// <include file='IConfig.xml' path='//Method[@name="Get"]/docs/*' />
|
||||
public string GetString (string key)
|
||||
{
|
||||
return Get (key);
|
||||
}
|
||||
|
||||
/// <include file='IConfig.xml' path='//Method[@name="GetDefault"]/docs/*' />
|
||||
public string GetString (string key, string defaultValue)
|
||||
{
|
||||
return Get (key, defaultValue);
|
||||
}
|
||||
|
||||
/// <include file='IConfig.xml' path='//Method[@name="GetInt"]/docs/*' />
|
||||
public int GetInt (string key)
|
||||
{
|
||||
string text = Get (key);
|
||||
|
||||
if (text == null) {
|
||||
throw new ArgumentException ("Value not found: " + key);
|
||||
}
|
||||
|
||||
return Convert.ToInt32 (text, format);
|
||||
}
|
||||
|
||||
/// <include file='IConfig.xml' path='//Method[@name="GetIntAlias"]/docs/*' />
|
||||
public int GetInt (string key, bool fromAlias)
|
||||
{
|
||||
if (!fromAlias) {
|
||||
return GetInt (key);
|
||||
}
|
||||
|
||||
string result = Get (key);
|
||||
|
||||
if (result == null) {
|
||||
throw new ArgumentException ("Value not found: " + key);
|
||||
}
|
||||
|
||||
return GetIntAlias (key, result);
|
||||
}
|
||||
|
||||
/// <include file='IConfig.xml' path='//Method[@name="GetIntDefault"]/docs/*' />
|
||||
public int GetInt (string key, int defaultValue)
|
||||
{
|
||||
string result = Get (key);
|
||||
|
||||
return (result == null)
|
||||
? defaultValue
|
||||
: Convert.ToInt32 (result, format);
|
||||
}
|
||||
|
||||
/// <include file='IConfig.xml' path='//Method[@name="GetIntDefaultAlias"]/docs/*' />
|
||||
public int GetInt (string key, int defaultValue, bool fromAlias)
|
||||
{
|
||||
if (!fromAlias) {
|
||||
return GetInt (key, defaultValue);
|
||||
}
|
||||
|
||||
string result = Get (key);
|
||||
|
||||
return (result == null) ? defaultValue : GetIntAlias (key, result);
|
||||
}
|
||||
|
||||
/// <include file='IConfig.xml' path='//Method[@name="GetLong"]/docs/*' />
|
||||
public long GetLong (string key)
|
||||
{
|
||||
string text = Get (key);
|
||||
|
||||
if (text == null) {
|
||||
throw new ArgumentException ("Value not found: " + key);
|
||||
}
|
||||
|
||||
return Convert.ToInt64 (text, format);
|
||||
}
|
||||
|
||||
/// <include file='IConfig.xml' path='//Method[@name="GetLongDefault"]/docs/*' />
|
||||
public long GetLong (string key, long defaultValue)
|
||||
{
|
||||
string result = Get (key);
|
||||
|
||||
return (result == null)
|
||||
? defaultValue
|
||||
: Convert.ToInt64 (result, format);
|
||||
}
|
||||
|
||||
/// <include file='IConfig.xml' path='//Method[@name="GetBoolean"]/docs/*' />
|
||||
public bool GetBoolean (string key)
|
||||
{
|
||||
string text = Get (key);
|
||||
|
||||
if (text == null) {
|
||||
throw new ArgumentException ("Value not found: " + key);
|
||||
}
|
||||
|
||||
return GetBooleanAlias (text);
|
||||
}
|
||||
|
||||
/// <include file='IConfig.xml' path='//Method[@name="GetBooleanDefault"]/docs/*' />
|
||||
public bool GetBoolean (string key, bool defaultValue)
|
||||
{
|
||||
string text = Get (key);
|
||||
|
||||
return (text == null) ? defaultValue : GetBooleanAlias (text);
|
||||
}
|
||||
|
||||
/// <include file='IConfig.xml' path='//Method[@name="GetFloat"]/docs/*' />
|
||||
public float GetFloat (string key)
|
||||
{
|
||||
string text = Get (key);
|
||||
|
||||
if (text == null) {
|
||||
throw new ArgumentException ("Value not found: " + key);
|
||||
}
|
||||
|
||||
return Convert.ToSingle (text, format);
|
||||
}
|
||||
|
||||
/// <include file='IConfig.xml' path='//Method[@name="GetFloatDefault"]/docs/*' />
|
||||
public float GetFloat (string key, float defaultValue)
|
||||
{
|
||||
string result = Get (key);
|
||||
|
||||
return (result == null)
|
||||
? defaultValue
|
||||
: Convert.ToSingle (result, format);
|
||||
}
|
||||
|
||||
/// <include file='IConfig.xml' path='//Method[@name="GetDouble"]/docs/*' />
|
||||
public double GetDouble (string key)
|
||||
{
|
||||
string text = Get (key);
|
||||
|
||||
if (text == null) {
|
||||
throw new ArgumentException ("Value not found: " + key);
|
||||
}
|
||||
|
||||
return Convert.ToDouble (text, format);
|
||||
}
|
||||
|
||||
/// <include file='IConfig.xml' path='//Method[@name="GetDoubleDefault"]/docs/*' />
|
||||
public double GetDouble (string key, double defaultValue)
|
||||
{
|
||||
string result = Get (key);
|
||||
|
||||
return (result == null)
|
||||
? defaultValue
|
||||
: Convert.ToDouble (result, format);
|
||||
}
|
||||
|
||||
/// <include file='IConfig.xml' path='//Method[@name="GetKeys"]/docs/*' />
|
||||
public string[] GetKeys ()
|
||||
{
|
||||
string[] result = new string[keys.Keys.Count];
|
||||
|
||||
keys.Keys.CopyTo (result, 0);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/// <include file='IConfig.xml' path='//Method[@name="GetValues"]/docs/*' />
|
||||
public string[] GetValues ()
|
||||
{
|
||||
string[] result = new string[keys.Values.Count];
|
||||
|
||||
keys.Values.CopyTo (result, 0);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/// <include file='ConfigBase.xml' path='//Method[@name="Add"]/docs/*' />
|
||||
public void Add (string key, string value)
|
||||
{
|
||||
keys.Add (key, value);
|
||||
}
|
||||
|
||||
/// <include file='IConfig.xml' path='//Method[@name="Set"]/docs/*' />
|
||||
public virtual void Set (string key, object value)
|
||||
{
|
||||
if (value == null) {
|
||||
throw new ArgumentNullException ("Value cannot be null");
|
||||
}
|
||||
|
||||
if (Get (key) == null) {
|
||||
this.Add (key, value.ToString ());
|
||||
} else {
|
||||
keys[key] = value.ToString ();
|
||||
}
|
||||
|
||||
if (ConfigSource.AutoSave) {
|
||||
ConfigSource.Save ();
|
||||
}
|
||||
|
||||
OnKeySet (new ConfigKeyEventArgs (key, value.ToString ()));
|
||||
}
|
||||
|
||||
/// <include file='IConfig.xml' path='//Method[@name="Remove"]/docs/*' />
|
||||
public virtual void Remove (string key)
|
||||
{
|
||||
if (key == null) {
|
||||
throw new ArgumentNullException ("Key cannot be null");
|
||||
}
|
||||
|
||||
if (Get (key) != null) {
|
||||
string keyValue = null;
|
||||
if (KeySet != null) {
|
||||
keyValue = Get (key);
|
||||
}
|
||||
keys.Remove (key);
|
||||
|
||||
OnKeyRemoved (new ConfigKeyEventArgs (key, keyValue));
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region Public events
|
||||
/// <include file='IConfig.xml' path='//Event[@name="KeySet"]/docs/*' />
|
||||
public event ConfigKeyEventHandler KeySet;
|
||||
|
||||
/// <include file='IConfig.xml' path='//Event[@name="KeyRemoved"]/docs/*' />
|
||||
public event ConfigKeyEventHandler KeyRemoved;
|
||||
#endregion
|
||||
|
||||
#region Protected methods
|
||||
/// <include file='ConfigBase.xml' path='//Method[@name="OnKeySet"]/docs/*' />
|
||||
protected void OnKeySet (ConfigKeyEventArgs e)
|
||||
{
|
||||
if (KeySet != null) {
|
||||
KeySet (this, e);
|
||||
}
|
||||
}
|
||||
|
||||
/// <include file='ConfigBase.xml' path='//Method[@name="OnKeyRemoved"]/docs/*' />
|
||||
protected void OnKeyRemoved (ConfigKeyEventArgs e)
|
||||
{
|
||||
if (KeyRemoved != null) {
|
||||
KeyRemoved (this, e);
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region Private methods
|
||||
/// <summary>
|
||||
/// Renames the config to the new name.
|
||||
/// </summary>
|
||||
private void Rename (string name)
|
||||
{
|
||||
this.ConfigSource.Configs.Remove (this);
|
||||
configName = name;
|
||||
this.ConfigSource.Configs.Add (this);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns the integer alias first from this IConfig then
|
||||
/// the parent if there is none.
|
||||
/// </summary>
|
||||
private int GetIntAlias (string key, string alias)
|
||||
{
|
||||
int result = -1;
|
||||
|
||||
if (aliasText.ContainsInt (key, alias)) {
|
||||
result = aliasText.GetInt (key, alias);
|
||||
} else {
|
||||
result = ConfigSource.Alias.GetInt (key, alias);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns the boolean alias first from this IConfig then
|
||||
/// the parent if there is none.
|
||||
/// </summary>
|
||||
private bool GetBooleanAlias (string key)
|
||||
{
|
||||
bool result = false;
|
||||
|
||||
if (aliasText.ContainsBoolean (key)) {
|
||||
result = aliasText.GetBoolean (key);
|
||||
} else {
|
||||
if (ConfigSource.Alias.ContainsBoolean (key)) {
|
||||
result = ConfigSource.Alias.GetBoolean (key);
|
||||
} else {
|
||||
throw new ArgumentException
|
||||
("Alias value not found: " + key
|
||||
+ ". Add it to the Alias property.");
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
264
ExtensionLoader/Config/ConfigCollection.cs
Normal file
264
ExtensionLoader/Config/ConfigCollection.cs
Normal file
@@ -0,0 +1,264 @@
|
||||
#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.Collections;
|
||||
|
||||
namespace ExtensionLoader.Config
|
||||
{
|
||||
#region ConfigEventHandler class
|
||||
/// <include file='ConfigEventArgs.xml' path='//Delegate[@name="ConfigEventHandler"]/docs/*' />
|
||||
public delegate void ConfigEventHandler (object sender, ConfigEventArgs e);
|
||||
|
||||
/// <include file='ConfigEventArgs.xml' path='//Class[@name="ConfigEventArgs"]/docs/*' />
|
||||
public class ConfigEventArgs : EventArgs
|
||||
{
|
||||
IConfig config = null;
|
||||
|
||||
/// <include file='ConfigEventArgs.xml' path='//Constructor[@name="ConstructorIConfig"]/docs/*' />
|
||||
public ConfigEventArgs (IConfig config)
|
||||
{
|
||||
this.config = config;
|
||||
}
|
||||
|
||||
/// <include file='ConfigEventArgs.xml' path='//Property[@name="Config"]/docs/*' />
|
||||
public IConfig Config
|
||||
{
|
||||
get { return config; }
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
|
||||
/// <include file='ConfigCollection.xml' path='//Class[@name="ConfigCollection"]/docs/*' />
|
||||
public class ConfigCollection : ICollection, IEnumerable, IList
|
||||
{
|
||||
#region Private variables
|
||||
ArrayList configList = new ArrayList ();
|
||||
ConfigSourceBase owner = null;
|
||||
#endregion
|
||||
|
||||
#region Constructors
|
||||
/// <include file='ConfigCollection.xml' path='//Constructor[@name="Constructor"]/docs/*' />
|
||||
public ConfigCollection (ConfigSourceBase owner)
|
||||
{
|
||||
this.owner = owner;
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region Public properties
|
||||
/// <include file='ConfigCollection.xml' path='//Property[@name="Count"]/docs/*' />
|
||||
public int Count
|
||||
{
|
||||
get { return configList.Count; }
|
||||
}
|
||||
|
||||
/// <include file='ConfigCollection.xml' path='//Property[@name="IsSynchronized"]/docs/*' />
|
||||
public bool IsSynchronized
|
||||
{
|
||||
get { return false; }
|
||||
}
|
||||
|
||||
/// <include file='ConfigCollection.xml' path='//Property[@name="SyncRoot"]/docs/*' />
|
||||
public object SyncRoot
|
||||
{
|
||||
get { return this; }
|
||||
}
|
||||
|
||||
/// <include file='ConfigCollection.xml' path='//Property[@name="ItemIndex"]/docs/*' />
|
||||
public IConfig this[int index]
|
||||
{
|
||||
get { return (IConfig)configList[index]; }
|
||||
}
|
||||
|
||||
/// <include file='ConfigCollection.xml' path='//Property[@name="ItemIndex"]/docs/*' />
|
||||
object IList.this[int index]
|
||||
{
|
||||
get { return configList[index]; }
|
||||
set { }
|
||||
}
|
||||
|
||||
/// <include file='ConfigCollection.xml' path='//Property[@name="ItemName"]/docs/*' />
|
||||
public IConfig this[string configName]
|
||||
{
|
||||
get
|
||||
{
|
||||
IConfig result = null;
|
||||
|
||||
foreach (IConfig config in configList)
|
||||
{
|
||||
if (config.Name == configName) {
|
||||
result = config;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
/// <include file='ConfigCollection.xml' path='//Property[@name="IsFixedSize"]/docs/*' />
|
||||
public bool IsFixedSize
|
||||
{
|
||||
get { return false; }
|
||||
}
|
||||
|
||||
/// <include file='ConfigCollection.xml' path='//Property[@name="IsReadOnly"]/docs/*' />
|
||||
public bool IsReadOnly
|
||||
{
|
||||
get { return false; }
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region Public methods
|
||||
/// <include file='ConfigCollection.xml' path='//Method[@name="Add"]/docs/*' />
|
||||
public void Add (IConfig config)
|
||||
{
|
||||
if (configList.Contains (config)) {
|
||||
throw new ArgumentException ("IConfig already exists");
|
||||
}
|
||||
IConfig existingConfig = this[config.Name];
|
||||
|
||||
if (existingConfig != null) {
|
||||
// Set all new keys
|
||||
string[] keys = config.GetKeys ();
|
||||
for (int i = 0; i < keys.Length; i++)
|
||||
{
|
||||
existingConfig.Set (keys[i], config.Get (keys[i]));
|
||||
}
|
||||
} else {
|
||||
configList.Add (config);
|
||||
OnConfigAdded (new ConfigEventArgs (config));
|
||||
}
|
||||
}
|
||||
|
||||
/// <include file='ConfigCollection.xml' path='//Method[@name="Add"]/docs/*' />
|
||||
int IList.Add (object config)
|
||||
{
|
||||
IConfig newConfig = config as IConfig;
|
||||
|
||||
if (newConfig == null) {
|
||||
throw new Exception ("Must be an IConfig");
|
||||
} else {
|
||||
this.Add (newConfig);
|
||||
return IndexOf (newConfig);
|
||||
}
|
||||
}
|
||||
|
||||
/// <include file='ConfigCollection.xml' path='//Method[@name="AddName"]/docs/*' />
|
||||
public IConfig Add (string name)
|
||||
{
|
||||
ConfigBase result = null;
|
||||
|
||||
if (this[name] == null) {
|
||||
result = new ConfigBase (name, owner);
|
||||
configList.Add (result);
|
||||
OnConfigAdded (new ConfigEventArgs (result));
|
||||
} else {
|
||||
throw new ArgumentException ("An IConfig of that name already exists");
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/// <include file='ConfigCollection.xml' path='//Method[@name="Remove"]/docs/*' />
|
||||
public void Remove (IConfig config)
|
||||
{
|
||||
configList.Remove (config);
|
||||
OnConfigRemoved (new ConfigEventArgs (config));
|
||||
}
|
||||
|
||||
/// <include file='ConfigCollection.xml' path='//Method[@name="Remove"]/docs/*' />
|
||||
public void Remove (object config)
|
||||
{
|
||||
configList.Remove (config);
|
||||
OnConfigRemoved (new ConfigEventArgs ((IConfig)config));
|
||||
}
|
||||
|
||||
/// <include file='ConfigCollection.xml' path='//Method[@name="RemoveAt"]/docs/*' />
|
||||
public void RemoveAt (int index)
|
||||
{
|
||||
IConfig config = (IConfig)configList[index];
|
||||
configList.RemoveAt (index);
|
||||
OnConfigRemoved (new ConfigEventArgs (config));
|
||||
}
|
||||
|
||||
/// <include file='ConfigCollection.xml' path='//Method[@name="Clear"]/docs/*' />
|
||||
public void Clear ()
|
||||
{
|
||||
configList.Clear ();
|
||||
}
|
||||
|
||||
/// <include file='ConfigCollection.xml' path='//Method[@name="GetEnumerator"]/docs/*' />
|
||||
public IEnumerator GetEnumerator ()
|
||||
{
|
||||
return configList.GetEnumerator ();
|
||||
}
|
||||
|
||||
/// <include file='ConfigCollection.xml' path='//Method[@name="CopyTo"]/docs/*' />
|
||||
public void CopyTo (Array array, int index)
|
||||
{
|
||||
configList.CopyTo (array, index);
|
||||
}
|
||||
|
||||
/// <include file='ConfigCollection.xml' path='//Method[@name="CopyToStrong"]/docs/*' />
|
||||
public void CopyTo (IConfig[] array, int index)
|
||||
{
|
||||
((ICollection)configList).CopyTo (array, index);
|
||||
}
|
||||
|
||||
/// <include file='ConfigCollection.xml' path='//Method[@name="Contains"]/docs/*' />
|
||||
public bool Contains (object config)
|
||||
{
|
||||
return configList.Contains (config);
|
||||
}
|
||||
|
||||
/// <include file='ConfigCollection.xml' path='//Method[@name="IndexOf"]/docs/*' />
|
||||
public int IndexOf (object config)
|
||||
{
|
||||
return configList.IndexOf (config);
|
||||
}
|
||||
|
||||
/// <include file='ConfigCollection.xml' path='//Method[@name="Insert"]/docs/*' />
|
||||
public void Insert (int index, object config)
|
||||
{
|
||||
configList.Insert (index, config);
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region Public events
|
||||
/// <include file='ConfigCollection.xml' path='//Event[@name="ConfigAdded"]/docs/*' />
|
||||
public event ConfigEventHandler ConfigAdded;
|
||||
|
||||
/// <include file='ConfigCollection.xml' path='//Event[@name="ConfigRemoved"]/docs/*' />
|
||||
public event ConfigEventHandler ConfigRemoved;
|
||||
#endregion
|
||||
|
||||
#region Protected methods
|
||||
/// <include file='ConfigCollection.xml' path='//Method[@name="OnConfigAdded"]/docs/*' />
|
||||
protected void OnConfigAdded (ConfigEventArgs e)
|
||||
{
|
||||
if (ConfigAdded != null) {
|
||||
ConfigAdded (this, e);
|
||||
}
|
||||
}
|
||||
|
||||
/// <include file='ConfigCollection.xml' path='//Method[@name="OnConfigRemoved"]/docs/*' />
|
||||
protected void OnConfigRemoved (ConfigEventArgs e)
|
||||
{
|
||||
if (ConfigRemoved != null) {
|
||||
ConfigRemoved (this, e);
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region Private methods
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
219
ExtensionLoader/Config/ConfigSourceBase.cs
Normal file
219
ExtensionLoader/Config/ConfigSourceBase.cs
Normal file
@@ -0,0 +1,219 @@
|
||||
#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.Text;
|
||||
using System.Collections;
|
||||
|
||||
namespace ExtensionLoader.Config
|
||||
{
|
||||
/// <include file='IConfigSource.xml' path='//Interface[@name="IConfigSource"]/docs/*' />
|
||||
public abstract class ConfigSourceBase : IConfigSource
|
||||
{
|
||||
#region Private variables
|
||||
ArrayList sourceList = new ArrayList ();
|
||||
ConfigCollection configList = null;
|
||||
bool autoSave = false;
|
||||
AliasText alias = new AliasText ();
|
||||
#endregion
|
||||
|
||||
#region Constructors
|
||||
/// <include file='ConfigSourceBase.xml' path='//Constructor[@name="Constructor"]/docs/*' />
|
||||
public ConfigSourceBase ()
|
||||
{
|
||||
configList = new ConfigCollection (this);
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region Public properties
|
||||
/// <include file='IConfigSource.xml' path='//Property[@name="Configs"]/docs/*' />
|
||||
public ConfigCollection Configs
|
||||
{
|
||||
get { return configList; }
|
||||
}
|
||||
|
||||
/// <include file='IConfigSource.xml' path='//Property[@name="AutoSave"]/docs/*' />
|
||||
public bool AutoSave
|
||||
{
|
||||
get { return autoSave; }
|
||||
set { autoSave = value; }
|
||||
}
|
||||
|
||||
/// <include file='IConfigSource.xml' path='//Property[@name="Alias"]/docs/*' />
|
||||
public AliasText Alias
|
||||
{
|
||||
get { return alias; }
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region Public methods
|
||||
/// <include file='IConfigSource.xml' path='//Method[@name="Merge"]/docs/*' />
|
||||
public void Merge (IConfigSource source)
|
||||
{
|
||||
if (!sourceList.Contains (source)) {
|
||||
sourceList.Add (source);
|
||||
}
|
||||
|
||||
foreach (IConfig config in source.Configs)
|
||||
{
|
||||
this.Configs.Add (config);
|
||||
}
|
||||
}
|
||||
|
||||
/// <include file='IConfigSource.xml' path='//Method[@name="AddConfig"]/docs/*' />
|
||||
public virtual IConfig AddConfig (string name)
|
||||
{
|
||||
return configList.Add (name);
|
||||
}
|
||||
|
||||
/// <include file='IConfigSource.xml' path='//Method[@name="GetExpanded"]/docs/*' />
|
||||
public string GetExpanded (IConfig config, string key)
|
||||
{
|
||||
return Expand (config, key, false);
|
||||
}
|
||||
|
||||
/// <include file='IConfigSource.xml' path='//Method[@name="Save"]/docs/*' />
|
||||
public virtual void Save ()
|
||||
{
|
||||
OnSaved (new EventArgs ());
|
||||
}
|
||||
|
||||
/// <include file='IConfigSource.xml' path='//Method[@name="Reload"]/docs/*' />
|
||||
public virtual void Reload ()
|
||||
{
|
||||
OnReloaded (new EventArgs ());
|
||||
}
|
||||
|
||||
/// <include file='IConfigSource.xml' path='//Method[@name="ExpandKeyValues"]/docs/*' />
|
||||
public void ExpandKeyValues ()
|
||||
{
|
||||
string[] keys = null;
|
||||
|
||||
foreach (IConfig config in configList)
|
||||
{
|
||||
keys = config.GetKeys ();
|
||||
for (int i = 0; i < keys.Length; i++)
|
||||
{
|
||||
Expand (config, keys[i], true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <include file='IConfigSource.xml' path='//Method[@name="ReplaceKeyValues"]/docs/*' />
|
||||
public void ReplaceKeyValues ()
|
||||
{
|
||||
ExpandKeyValues ();
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region Public events
|
||||
/// <include file='IConfigSource.xml' path='//Event[@name="Reloaded"]/docs/*' />
|
||||
public event EventHandler Reloaded;
|
||||
|
||||
/// <include file='IConfigSource.xml' path='//Event[@name="Saved"]/docs/*' />
|
||||
public event EventHandler Saved;
|
||||
#endregion
|
||||
|
||||
#region Protected methods
|
||||
/// <include file='ConfigSourceBase.xml' path='//Method[@name="OnReloaded"]/docs/*' />
|
||||
protected void OnReloaded (EventArgs e)
|
||||
{
|
||||
if (Reloaded != null) {
|
||||
Reloaded (this, e);
|
||||
}
|
||||
}
|
||||
|
||||
/// <include file='ConfigSourceBase.xml' path='//Method[@name="OnSaved"]/docs/*' />
|
||||
protected void OnSaved (EventArgs e)
|
||||
{
|
||||
if (Saved != null) {
|
||||
Saved (this, e);
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region Private methods
|
||||
/// <summary>
|
||||
/// Expands key values from the given IConfig.
|
||||
/// </summary>
|
||||
private string Expand (IConfig config, string key, bool setValue)
|
||||
{
|
||||
string result = config.Get (key);
|
||||
if (result == null) {
|
||||
throw new ArgumentException (String.Format ("[{0}] not found in [{1}]",
|
||||
key, config.Name));
|
||||
}
|
||||
|
||||
while (true)
|
||||
{
|
||||
int startIndex = result.IndexOf ("${", 0);
|
||||
if (startIndex == -1) {
|
||||
break;
|
||||
}
|
||||
|
||||
int endIndex = result.IndexOf ("}", startIndex + 2);
|
||||
if (endIndex == -1) {
|
||||
break;
|
||||
}
|
||||
|
||||
string search = result.Substring (startIndex + 2,
|
||||
endIndex - (startIndex + 2));
|
||||
|
||||
if (search == key) {
|
||||
// Prevent infinite recursion
|
||||
throw new ArgumentException
|
||||
("Key cannot have a expand value of itself: " + key);
|
||||
}
|
||||
|
||||
string replace = ExpandValue (config, search);
|
||||
|
||||
result = result.Replace("${" + search + "}", replace);
|
||||
}
|
||||
|
||||
if (setValue) {
|
||||
config.Set(key, result);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns the replacement value of a config.
|
||||
/// </summary>
|
||||
private string ExpandValue (IConfig config, string search)
|
||||
{
|
||||
string result = null;
|
||||
|
||||
string[] replaces = search.Split ('|');
|
||||
|
||||
if (replaces.Length > 1) {
|
||||
IConfig newConfig = this.Configs[replaces[0]];
|
||||
if (newConfig == null) {
|
||||
throw new ArgumentException ("Expand config not found: "
|
||||
+ replaces[0]);
|
||||
}
|
||||
result = newConfig.Get (replaces[1]);
|
||||
if (result == null) {
|
||||
throw new ArgumentException ("Expand key not found: "
|
||||
+ replaces[1]);
|
||||
}
|
||||
} else {
|
||||
result = config.Get (search);
|
||||
|
||||
if (result == null) {
|
||||
throw new ArgumentException ("Key not found: " + search);
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
99
ExtensionLoader/Config/IConfig.cs
Normal file
99
ExtensionLoader/Config/IConfig.cs
Normal file
@@ -0,0 +1,99 @@
|
||||
#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;
|
||||
|
||||
namespace ExtensionLoader.Config
|
||||
{
|
||||
/// <include file='IConfig.xml' path='//Interface[@name="IConfig"]/docs/*' />
|
||||
public interface IConfig
|
||||
{
|
||||
/// <include file='IConfig.xml' path='//Property[@name="ConfigSource"]/docs/*' />
|
||||
IConfigSource ConfigSource { get; }
|
||||
|
||||
/// <include file='IConfig.xml' path='//Property[@name="Name"]/docs/*' />
|
||||
string Name { get; set; }
|
||||
|
||||
/// <include file='IConfig.xml' path='//Property[@name="Alias"]/docs/*' />
|
||||
AliasText Alias { get; }
|
||||
|
||||
/// <include file='IConfig.xml' path='//Method[@name="Contains"]/docs/*' />
|
||||
bool Contains (string key);
|
||||
|
||||
/// <include file='IConfig.xml' path='//Method[@name="Get"]/docs/*' />
|
||||
string Get (string key);
|
||||
|
||||
/// <include file='IConfig.xml' path='//Method[@name="GetDefault"]/docs/*' />
|
||||
string Get (string key, string defaultValue);
|
||||
|
||||
/// <include file='IConfig.xml' path='//Method[@name="GetExpanded"]/docs/*' />
|
||||
string GetExpanded (string key);
|
||||
|
||||
/// <include file='IConfig.xml' path='//Method[@name="Get"]/docs/*' />
|
||||
string GetString (string key);
|
||||
|
||||
/// <include file='IConfig.xml' path='//Method[@name="GetDefault"]/docs/*' />
|
||||
string GetString (string key, string defaultValue);
|
||||
|
||||
/// <include file='IConfig.xml' path='//Method[@name="GetInt"]/docs/*' />
|
||||
int GetInt (string key);
|
||||
|
||||
/// <include file='IConfig.xml' path='//Method[@name="GetIntAlias"]/docs/*' />
|
||||
int GetInt (string key, bool fromAlias);
|
||||
|
||||
/// <include file='IConfig.xml' path='//Method[@name="GetIntDefault"]/docs/*' />
|
||||
int GetInt (string key, int defaultValue);
|
||||
|
||||
/// <include file='IConfig.xml' path='//Method[@name="GetIntDefaultAlias"]/docs/*' />
|
||||
int GetInt (string key, int defaultValue, bool fromAlias);
|
||||
|
||||
/// <include file='IConfig.xml' path='//Method[@name="GetLong"]/docs/*' />
|
||||
long GetLong (string key);
|
||||
|
||||
/// <include file='IConfig.xml' path='//Method[@name="GetLongDefault"]/docs/*' />
|
||||
long GetLong (string key, long defaultValue);
|
||||
|
||||
/// <include file='IConfig.xml' path='//Method[@name="GetBoolean"]/docs/*' />
|
||||
bool GetBoolean (string key);
|
||||
|
||||
/// <include file='IConfig.xml' path='//Method[@name="GetBooleanDefault"]/docs/*' />
|
||||
bool GetBoolean (string key, bool defaultValue);
|
||||
|
||||
/// <include file='IConfig.xml' path='//Method[@name="GetFloat"]/docs/*' />
|
||||
float GetFloat (string key);
|
||||
|
||||
/// <include file='IConfig.xml' path='//Method[@name="GetFloatDefault"]/docs/*' />
|
||||
float GetFloat (string key, float defaultValue);
|
||||
|
||||
/// <include file='IConfig.xml' path='//Method[@name="GetDouble"]/docs/*' />
|
||||
double GetDouble (string key);
|
||||
|
||||
/// <include file='IConfig.xml' path='//Method[@name="GetDoubleDefault"]/docs/*' />
|
||||
double GetDouble (string key, double defaultValue);
|
||||
|
||||
/// <include file='IConfig.xml' path='//Method[@name="GetKeys"]/docs/*' />
|
||||
string[] GetKeys ();
|
||||
|
||||
/// <include file='IConfig.xml' path='//Method[@name="GetValues"]/docs/*' />
|
||||
string[] GetValues ();
|
||||
|
||||
/// <include file='IConfig.xml' path='//Method[@name="Set"]/docs/*' />
|
||||
void Set (string key, object value);
|
||||
|
||||
/// <include file='IConfig.xml' path='//Method[@name="Remove"]/docs/*' />
|
||||
void Remove (string key);
|
||||
|
||||
/// <include file='IConfig.xml' path='//Event[@name="KeySet"]/docs/*' />
|
||||
event ConfigKeyEventHandler KeySet;
|
||||
|
||||
/// <include file='IConfig.xml' path='//Event[@name="KeyRemoved"]/docs/*' />
|
||||
event ConfigKeyEventHandler KeyRemoved;
|
||||
}
|
||||
}
|
||||
55
ExtensionLoader/Config/IConfigSource.cs
Normal file
55
ExtensionLoader/Config/IConfigSource.cs
Normal file
@@ -0,0 +1,55 @@
|
||||
#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;
|
||||
|
||||
namespace ExtensionLoader.Config
|
||||
{
|
||||
/// <include file='IConfigSource.xml' path='//Interface[@name="IConfigSource"]/docs/*' />
|
||||
public interface IConfigSource
|
||||
{
|
||||
/// <include file='IConfigSource.xml' path='//Property[@name="Configs"]/docs/*' />
|
||||
ConfigCollection Configs { get; }
|
||||
|
||||
/// <include file='IConfigSource.xml' path='//Property[@name="AutoSave"]/docs/*' />
|
||||
bool AutoSave { get; set; }
|
||||
|
||||
/// <include file='IConfigSource.xml' path='//Property[@name="Alias"]/docs/*' />
|
||||
AliasText Alias { get; }
|
||||
|
||||
/// <include file='IConfigSource.xml' path='//Method[@name="Merge"]/docs/*' />
|
||||
void Merge (IConfigSource source);
|
||||
|
||||
/// <include file='IConfigSource.xml' path='//Method[@name="Save"]/docs/*' />
|
||||
void Save ();
|
||||
|
||||
/// <include file='IConfigSource.xml' path='//Method[@name="Reload"]/docs/*' />
|
||||
void Reload ();
|
||||
|
||||
/// <include file='IConfigSource.xml' path='//Method[@name="AddConfig"]/docs/*' />
|
||||
IConfig AddConfig (string name);
|
||||
|
||||
/// <include file='IConfigSource.xml' path='//Method[@name="GetExpanded"]/docs/*' />
|
||||
string GetExpanded (IConfig config, string key);
|
||||
|
||||
/// <include file='IConfigSource.xml' path='//Method[@name="ExpandKeyValues"]/docs/*' />
|
||||
void ExpandKeyValues ();
|
||||
|
||||
/// <include file='IConfigSource.xml' path='//Method[@name="ReplaceKeyValues"]/docs/*' />
|
||||
void ReplaceKeyValues ();
|
||||
|
||||
/// <include file='IConfigSource.xml' path='//Event[@name="Reloaded"]/docs/*' />
|
||||
event EventHandler Reloaded;
|
||||
|
||||
/// <include file='IConfigSource.xml' path='//Event[@name="Saved"]/docs/*' />
|
||||
event EventHandler Saved;
|
||||
}
|
||||
}
|
||||
90
ExtensionLoader/Config/IniConfig.cs
Normal file
90
ExtensionLoader/Config/IniConfig.cs
Normal file
@@ -0,0 +1,90 @@
|
||||
#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.Collections;
|
||||
using System.Globalization;
|
||||
using ExtensionLoader.Util;
|
||||
|
||||
namespace ExtensionLoader.Config
|
||||
{
|
||||
/// <include file='IniConfig.xml' path='//Class[@name="IniConfig"]/docs/*' />
|
||||
public class IniConfig : ConfigBase
|
||||
{
|
||||
#region Private variables
|
||||
IniConfigSource parent = null;
|
||||
#endregion
|
||||
|
||||
#region Constructors
|
||||
/// <include file='IniConfig.xml' path='//Constructor[@name="Constructor"]/docs/*' />
|
||||
public IniConfig (string name, IConfigSource source)
|
||||
: base(name, source)
|
||||
{
|
||||
parent = (IniConfigSource)source;
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region Public properties
|
||||
#endregion
|
||||
|
||||
#region Public methods
|
||||
/// <include file='IniConfig.xml' path='//Method[@name="Get"]/docs/*' />
|
||||
public override string Get (string key)
|
||||
{
|
||||
if (!parent.CaseSensitive) {
|
||||
key = CaseInsensitiveKeyName (key);
|
||||
}
|
||||
|
||||
return base.Get (key);
|
||||
}
|
||||
|
||||
/// <include file='IniConfig.xml' path='//Method[@name="Set"]/docs/*' />
|
||||
public override void Set (string key, object value)
|
||||
{
|
||||
if (!parent.CaseSensitive) {
|
||||
key = CaseInsensitiveKeyName (key);
|
||||
}
|
||||
|
||||
base.Set (key, value);
|
||||
}
|
||||
|
||||
/// <include file='IniConfig.xml' path='//Method[@name="Remove"]/docs/*' />
|
||||
public override void Remove (string key)
|
||||
{
|
||||
if (!parent.CaseSensitive) {
|
||||
key = CaseInsensitiveKeyName (key);
|
||||
}
|
||||
|
||||
base.Remove (key);
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region Private methods
|
||||
/// <summary>
|
||||
/// Returns the key name if the case insensitivity is turned on.
|
||||
/// </summary>
|
||||
private string CaseInsensitiveKeyName (string key)
|
||||
{
|
||||
string result = null;
|
||||
|
||||
string lowerKey = key.ToLower ();
|
||||
foreach (string currentKey in keys.Keys)
|
||||
{
|
||||
if (currentKey.ToLower () == lowerKey) {
|
||||
result = currentKey;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return (result == null) ? key : result;
|
||||
}
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
329
ExtensionLoader/Config/IniConfigSource.cs
Normal file
329
ExtensionLoader/Config/IniConfigSource.cs
Normal file
@@ -0,0 +1,329 @@
|
||||
#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
|
||||
}
|
||||
}
|
||||
302
ExtensionLoader/Ini/IniDocument.cs
Normal file
302
ExtensionLoader/Ini/IniDocument.cs
Normal file
@@ -0,0 +1,302 @@
|
||||
#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.Util;
|
||||
|
||||
namespace ExtensionLoader.Ini
|
||||
{
|
||||
#region IniFileType enumeration
|
||||
/// <include file='IniDocument.xml' path='//Enum[@name="IniFileType"]/docs/*' />
|
||||
public enum IniFileType
|
||||
{
|
||||
/// <include file='IniDocument.xml' path='//Enum[@name="IniFileType"]/Value[@name="Standard"]/docs/*' />
|
||||
Standard,
|
||||
/// <include file='IniDocument.xml' path='//Enum[@name="IniFileType"]/Value[@name="PythonStyle"]/docs/*' />
|
||||
PythonStyle,
|
||||
/// <include file='IniDocument.xml' path='//Enum[@name="IniFileType"]/Value[@name="SambaStyle"]/docs/*' />
|
||||
SambaStyle,
|
||||
/// <include file='IniDocument.xml' path='//Enum[@name="IniFileType"]/Value[@name="MysqlStyle"]/docs/*' />
|
||||
MysqlStyle,
|
||||
/// <include file='IniDocument.xml' path='//Enum[@name="IniFileType"]/Value[@name="WindowsStyle"]/docs/*' />
|
||||
WindowsStyle
|
||||
}
|
||||
#endregion
|
||||
|
||||
/// <include file='IniDocument.xml' path='//Class[@name="IniDocument"]/docs/*' />
|
||||
public class IniDocument
|
||||
{
|
||||
#region Private variables
|
||||
IniSectionCollection sections = new IniSectionCollection ();
|
||||
ArrayList initialComment = new ArrayList ();
|
||||
IniFileType fileType = IniFileType.Standard;
|
||||
#endregion
|
||||
|
||||
#region Public properties
|
||||
/// <include file='IniDocument.xml' path='//Property[@name="FileType"]/docs/*' />
|
||||
public IniFileType FileType
|
||||
{
|
||||
get { return fileType; }
|
||||
set { fileType = value; }
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region Constructors
|
||||
/// <include file='IniDocument.xml' path='//Constructor[@name="ConstructorPath"]/docs/*' />
|
||||
public IniDocument (string filePath)
|
||||
{
|
||||
fileType = IniFileType.Standard;
|
||||
Load (filePath);
|
||||
}
|
||||
|
||||
/// <include file='IniDocument.xml' path='//Constructor[@name="ConstructorPathType"]/docs/*' />
|
||||
public IniDocument (string filePath, IniFileType type)
|
||||
{
|
||||
fileType = type;
|
||||
Load (filePath);
|
||||
}
|
||||
|
||||
/// <include file='IniDocument.xml' path='//Constructor[@name="ConstructorTextReader"]/docs/*' />
|
||||
public IniDocument (TextReader reader)
|
||||
{
|
||||
fileType = IniFileType.Standard;
|
||||
Load (reader);
|
||||
}
|
||||
|
||||
/// <include file='IniDocument.xml' path='//Constructor[@name="ConstructorTextReaderType"]/docs/*' />
|
||||
public IniDocument (TextReader reader, IniFileType type)
|
||||
{
|
||||
fileType = type;
|
||||
Load (reader);
|
||||
}
|
||||
|
||||
/// <include file='IniDocument.xml' path='//Constructor[@name="ConstructorStream"]/docs/*' />
|
||||
public IniDocument (Stream stream)
|
||||
{
|
||||
fileType = IniFileType.Standard;
|
||||
Load (stream);
|
||||
}
|
||||
|
||||
/// <include file='IniDocument.xml' path='//Constructor[@name="ConstructorStreamType"]/docs/*' />
|
||||
public IniDocument (Stream stream, IniFileType type)
|
||||
{
|
||||
fileType = type;
|
||||
Load (stream);
|
||||
}
|
||||
|
||||
/// <include file='IniDocument.xml' path='//Constructor[@name="ConstructorIniReader"]/docs/*' />
|
||||
public IniDocument (IniReader reader)
|
||||
{
|
||||
fileType = IniFileType.Standard;
|
||||
Load (reader);
|
||||
}
|
||||
|
||||
/// <include file='IniDocument.xml' path='//Constructor[@name="Constructor"]/docs/*' />
|
||||
public IniDocument ()
|
||||
{
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region Public methods
|
||||
/// <include file='IniDocument.xml' path='//Method[@name="LoadPath"]/docs/*' />
|
||||
public void Load (string filePath)
|
||||
{
|
||||
Load (new StreamReader (filePath));
|
||||
}
|
||||
|
||||
/// <include file='IniDocument.xml' path='//Method[@name="LoadTextReader"]/docs/*' />
|
||||
public void Load (TextReader reader)
|
||||
{
|
||||
Load (GetIniReader (reader, fileType));
|
||||
}
|
||||
|
||||
/// <include file='IniDocument.xml' path='//Method[@name="LoadStream"]/docs/*' />
|
||||
public void Load (Stream stream)
|
||||
{
|
||||
Load (new StreamReader (stream));
|
||||
}
|
||||
|
||||
/// <include file='IniDocument.xml' path='//Method[@name="LoadIniReader"]/docs/*' />
|
||||
public void Load (IniReader reader)
|
||||
{
|
||||
LoadReader (reader);
|
||||
}
|
||||
|
||||
/// <include file='IniSection.xml' path='//Property[@name="Comment"]/docs/*' />
|
||||
public IniSectionCollection Sections
|
||||
{
|
||||
get { return sections; }
|
||||
}
|
||||
|
||||
/// <include file='IniDocument.xml' path='//Method[@name="SaveTextWriter"]/docs/*' />
|
||||
public void Save (TextWriter textWriter)
|
||||
{
|
||||
IniWriter writer = GetIniWriter (textWriter, fileType);
|
||||
IniItem item = null;
|
||||
IniSection section = null;
|
||||
|
||||
foreach (string comment in initialComment)
|
||||
{
|
||||
writer.WriteEmpty (comment);
|
||||
}
|
||||
|
||||
for (int j = 0; j < sections.Count; j++)
|
||||
{
|
||||
section = sections[j];
|
||||
writer.WriteSection (section.Name, section.Comment);
|
||||
for (int i = 0; i < section.ItemCount; i++)
|
||||
{
|
||||
item = section.GetItem (i);
|
||||
switch (item.Type)
|
||||
{
|
||||
case IniType.Key:
|
||||
writer.WriteKey (item.Name, item.Value, item.Comment);
|
||||
break;
|
||||
case IniType.Empty:
|
||||
writer.WriteEmpty (item.Comment);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
writer.Close ();
|
||||
}
|
||||
|
||||
/// <include file='IniDocument.xml' path='//Method[@name="SavePath"]/docs/*' />
|
||||
public void Save (string filePath)
|
||||
{
|
||||
StreamWriter writer = new StreamWriter (filePath);
|
||||
Save (writer);
|
||||
writer.Close ();
|
||||
}
|
||||
|
||||
/// <include file='IniDocument.xml' path='//Method[@name="SaveStream"]/docs/*' />
|
||||
public void Save (Stream stream)
|
||||
{
|
||||
Save (new StreamWriter (stream));
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region Private methods
|
||||
/// <summary>
|
||||
/// Loads the file not saving comments.
|
||||
/// </summary>
|
||||
private void LoadReader (IniReader reader)
|
||||
{
|
||||
reader.IgnoreComments = false;
|
||||
bool sectionFound = false;
|
||||
IniSection section = null;
|
||||
|
||||
try {
|
||||
while (reader.Read ())
|
||||
{
|
||||
switch (reader.Type)
|
||||
{
|
||||
case IniType.Empty:
|
||||
if (!sectionFound) {
|
||||
initialComment.Add (reader.Comment);
|
||||
} else {
|
||||
section.Set (reader.Comment);
|
||||
}
|
||||
|
||||
break;
|
||||
case IniType.Section:
|
||||
sectionFound = true;
|
||||
// If section already exists then overwrite it
|
||||
if (sections[reader.Name] != null) {
|
||||
sections.Remove (reader.Name);
|
||||
}
|
||||
section = new IniSection (reader.Name, reader.Comment);
|
||||
sections.Add (section);
|
||||
|
||||
break;
|
||||
case IniType.Key:
|
||||
if (section.GetValue (reader.Name) == null) {
|
||||
section.Set (reader.Name, reader.Value, reader.Comment);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
} catch (Exception ex) {
|
||||
throw ex;
|
||||
} finally {
|
||||
// Always close the file
|
||||
reader.Close ();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns a proper INI reader depending upon the type parameter.
|
||||
/// </summary>
|
||||
private IniReader GetIniReader (TextReader reader, IniFileType type)
|
||||
{
|
||||
IniReader result = new IniReader (reader);
|
||||
|
||||
switch (type)
|
||||
{
|
||||
case IniFileType.Standard:
|
||||
// do nothing
|
||||
break;
|
||||
case IniFileType.PythonStyle:
|
||||
result.AcceptCommentAfterKey = false;
|
||||
result.SetCommentDelimiters (new char[] { ';', '#' });
|
||||
result.SetAssignDelimiters (new char[] { ':' });
|
||||
break;
|
||||
case IniFileType.SambaStyle:
|
||||
result.AcceptCommentAfterKey = false;
|
||||
result.SetCommentDelimiters (new char[] { ';', '#' });
|
||||
result.LineContinuation = true;
|
||||
break;
|
||||
case IniFileType.MysqlStyle:
|
||||
result.AcceptCommentAfterKey = false;
|
||||
result.AcceptNoAssignmentOperator = true;
|
||||
result.SetCommentDelimiters (new char[] { '#' });
|
||||
result.SetAssignDelimiters (new char[] { ':', '=' });
|
||||
break;
|
||||
case IniFileType.WindowsStyle:
|
||||
result.ConsumeAllKeyText = true;
|
||||
break;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns a proper IniWriter depending upon the type parameter.
|
||||
/// </summary>
|
||||
private IniWriter GetIniWriter (TextWriter reader, IniFileType type)
|
||||
{
|
||||
IniWriter result = new IniWriter (reader);
|
||||
|
||||
switch (type)
|
||||
{
|
||||
case IniFileType.Standard:
|
||||
case IniFileType.WindowsStyle:
|
||||
// do nothing
|
||||
break;
|
||||
case IniFileType.PythonStyle:
|
||||
result.AssignDelimiter = ':';
|
||||
result.CommentDelimiter = '#';
|
||||
break;
|
||||
case IniFileType.SambaStyle:
|
||||
case IniFileType.MysqlStyle:
|
||||
result.AssignDelimiter = '=';
|
||||
result.CommentDelimiter = '#';
|
||||
break;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
|
||||
121
ExtensionLoader/Ini/IniException.cs
Normal file
121
ExtensionLoader/Ini/IniException.cs
Normal file
@@ -0,0 +1,121 @@
|
||||
#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.Security;
|
||||
using System.Globalization;
|
||||
using System.Security.Permissions;
|
||||
using System.Runtime.Serialization;
|
||||
using System.Runtime.Serialization.Formatters.Binary;
|
||||
|
||||
|
||||
namespace ExtensionLoader.Ini
|
||||
{
|
||||
/// <include file='IniException.xml' path='//Class[@name="IniException"]/docs/*' />
|
||||
#if (NET_COMPACT_1_0)
|
||||
#else
|
||||
[Serializable]
|
||||
#endif
|
||||
public class IniException : SystemException /*, ISerializable */
|
||||
{
|
||||
#region Private variables
|
||||
IniReader iniReader = null;
|
||||
string message = "";
|
||||
#endregion
|
||||
|
||||
#region Public properties
|
||||
/// <include file='IniException.xml' path='//Property[@name="LinePosition"]/docs/*' />
|
||||
public int LinePosition
|
||||
{
|
||||
get {
|
||||
return (iniReader == null) ? 0 : iniReader.LinePosition;
|
||||
}
|
||||
}
|
||||
|
||||
/// <include file='IniException.xml' path='//Property[@name="LineNumber"]/docs/*' />
|
||||
public int LineNumber
|
||||
{
|
||||
get {
|
||||
return (iniReader == null) ? 0 : iniReader.LineNumber;
|
||||
}
|
||||
}
|
||||
|
||||
/// <include file='IniException.xml' path='//Property[@name="Message"]/docs/*' />
|
||||
public override string Message
|
||||
{
|
||||
get {
|
||||
if (iniReader == null) {
|
||||
return base.Message;
|
||||
}
|
||||
|
||||
return String.Format (CultureInfo.InvariantCulture, "{0} - Line: {1}, Position: {2}.",
|
||||
message, this.LineNumber, this.LinePosition);
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region Constructors
|
||||
/// <include file='IniException.xml' path='//Constructor[@name="Constructor"]/docs/*' />
|
||||
public IniException ()
|
||||
: base ()
|
||||
{
|
||||
this.message = "An error has occurred";
|
||||
}
|
||||
|
||||
/// <include file='IniException.xml' path='//Constructor[@name="ConstructorException"]/docs/*' />
|
||||
public IniException (string message, Exception exception)
|
||||
: base (message, exception)
|
||||
{
|
||||
}
|
||||
|
||||
/// <include file='IniException.xml' path='//Constructor[@name="ConstructorMessage"]/docs/*' />
|
||||
public IniException (string message)
|
||||
: base (message)
|
||||
{
|
||||
this.message = message;
|
||||
}
|
||||
|
||||
/// <include file='IniException.xml' path='//Constructor[@name="ConstructorTextReader"]/docs/*' />
|
||||
internal IniException (IniReader reader, string message)
|
||||
: this (message)
|
||||
{
|
||||
iniReader = reader;
|
||||
this.message = message;
|
||||
}
|
||||
|
||||
#if (NET_COMPACT_1_0)
|
||||
#else
|
||||
/// <include file='IniException.xml' path='//Constructor[@name="ConstructorSerialize"]/docs/*' />
|
||||
protected IniException (SerializationInfo info, StreamingContext context)
|
||||
: base (info, context)
|
||||
{
|
||||
}
|
||||
#endif
|
||||
#endregion
|
||||
|
||||
#region Public methods
|
||||
#if (NET_COMPACT_1_0)
|
||||
#else
|
||||
/// <include file='IniException.xml' path='//Method[@name="GetObjectData"]/docs/*' />
|
||||
[SecurityPermissionAttribute(SecurityAction.Demand,SerializationFormatter=true)]
|
||||
public override void GetObjectData (SerializationInfo info,
|
||||
StreamingContext context)
|
||||
{
|
||||
base.GetObjectData (info, context);
|
||||
if (iniReader != null) {
|
||||
info.AddValue ("lineNumber", iniReader.LineNumber);
|
||||
|
||||
info.AddValue ("linePosition", iniReader.LinePosition);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
54
ExtensionLoader/Ini/IniItem.cs
Normal file
54
ExtensionLoader/Ini/IniItem.cs
Normal file
@@ -0,0 +1,54 @@
|
||||
using System;
|
||||
|
||||
namespace ExtensionLoader.Ini
|
||||
{
|
||||
/// <include file='IniItem.xml' path='//Class[@name="IniItem"]/docs/*' />
|
||||
public class IniItem
|
||||
{
|
||||
#region Private variables
|
||||
IniType iniType = IniType.Empty;
|
||||
string iniName = "";
|
||||
string iniValue = "";
|
||||
string iniComment = null;
|
||||
#endregion
|
||||
|
||||
#region Public properties
|
||||
/// <include file='IniItem.xml' path='//Property[@name="Type"]/docs/*' />
|
||||
public IniType Type
|
||||
{
|
||||
get { return iniType; }
|
||||
set { iniType = value; }
|
||||
}
|
||||
|
||||
/// <include file='IniItem.xml' path='//Property[@name="Value"]/docs/*' />
|
||||
public string Value
|
||||
{
|
||||
get { return iniValue; }
|
||||
set { iniValue = value; }
|
||||
}
|
||||
|
||||
/// <include file='IniItem.xml' path='//Property[@name="Name"]/docs/*' />
|
||||
public string Name
|
||||
{
|
||||
get { return iniName; }
|
||||
}
|
||||
|
||||
/// <include file='IniItem.xml' path='//Property[@name="Comment"]/docs/*' />
|
||||
public string Comment
|
||||
{
|
||||
get { return iniComment; }
|
||||
set { iniComment = value; }
|
||||
}
|
||||
#endregion
|
||||
|
||||
/// <include file='IniItem.xml' path='//Constructor[@name="Constructor"]/docs/*' />
|
||||
internal protected IniItem (string name, string value, IniType type, string comment)
|
||||
{
|
||||
iniName = name;
|
||||
iniValue = value;
|
||||
iniType = type;
|
||||
iniComment = comment;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
652
ExtensionLoader/Ini/IniReader.cs
Normal file
652
ExtensionLoader/Ini/IniReader.cs
Normal file
@@ -0,0 +1,652 @@
|
||||
#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.Text;
|
||||
using System.Collections;
|
||||
|
||||
namespace ExtensionLoader.Ini
|
||||
{
|
||||
#region IniReadState enumeration
|
||||
/// <include file='IniReader.xml' path='//Enum[@name="IniReadState"]/docs/*' />
|
||||
public enum IniReadState : int
|
||||
{
|
||||
/// <include file='IniReader.xml' path='//Enum[@name="IniReadState"]/Value[@name="Closed"]/docs/*' />
|
||||
Closed,
|
||||
/// <include file='IniReader.xml' path='//Enum[@name="IniReadState"]/Value[@name="EndOfFile"]/docs/*' />
|
||||
EndOfFile,
|
||||
/// <include file='IniReader.xml' path='//Enum[@name="IniReadState"]/Value[@name="Error"]/docs/*' />
|
||||
Error,
|
||||
/// <include file='IniReader.xml' path='//Enum[@name="IniReadState"]/Value[@name="Initial"]/docs/*' />
|
||||
Initial,
|
||||
/// <include file='IniReader.xml' path='//Enum[@name="IniReadState"]/Value[@name="Interactive"]/docs/*' />
|
||||
Interactive
|
||||
};
|
||||
#endregion
|
||||
|
||||
#region IniType enumeration
|
||||
/// <include file='IniReader.xml' path='//Enum[@name="IniType"]/docs/*' />
|
||||
public enum IniType : int
|
||||
{
|
||||
/// <include file='IniReader.xml' path='//Enum[@name="IniType"]/Value[@name="Section"]/docs/*' />
|
||||
Section,
|
||||
/// <include file='IniReader.xml' path='//Enum[@name="IniType"]/Value[@name="Key"]/docs/*' />
|
||||
Key,
|
||||
/// <include file='IniReader.xml' path='//Enum[@name="IniType"]/Value[@name="Empty"]/docs/*' />
|
||||
Empty
|
||||
}
|
||||
#endregion
|
||||
|
||||
/// <include file='IniReader.xml' path='//Class[@name="IniReader"]/docs/*' />
|
||||
public class IniReader : IDisposable
|
||||
{
|
||||
#region Private variables
|
||||
int lineNumber = 1;
|
||||
int column = 1;
|
||||
IniType iniType = IniType.Empty;
|
||||
TextReader textReader = null;
|
||||
bool ignoreComments = false;
|
||||
StringBuilder name = new StringBuilder ();
|
||||
StringBuilder value = new StringBuilder ();
|
||||
StringBuilder comment = new StringBuilder ();
|
||||
IniReadState readState = IniReadState.Initial;
|
||||
bool hasComment = false;
|
||||
bool disposed = false;
|
||||
bool lineContinuation = false;
|
||||
bool acceptCommentAfterKey = true;
|
||||
bool acceptNoAssignmentOperator = false;
|
||||
bool consumeAllKeyText = false;
|
||||
char[] commentDelimiters = new char[] { ';' };
|
||||
char[] assignDelimiters = new char[] { '=' };
|
||||
#endregion
|
||||
|
||||
#region Public properties
|
||||
/// <include file='IniReader.xml' path='//Property[@name="Name"]/docs/*' />
|
||||
public string Name
|
||||
{
|
||||
get { return this.name.ToString (); }
|
||||
}
|
||||
|
||||
/// <include file='IniReader.xml' path='//Property[@name="Value"]/docs/*' />
|
||||
public string Value
|
||||
{
|
||||
get { return this.value.ToString (); }
|
||||
}
|
||||
|
||||
/// <include file='IniReader.xml' path='//Property[@name="Type"]/docs/*' />
|
||||
public IniType Type
|
||||
{
|
||||
get { return iniType; }
|
||||
}
|
||||
|
||||
/// <include file='IniReader.xml' path='//Property[@name="Comment"]/docs/*' />
|
||||
public string Comment
|
||||
{
|
||||
get { return (hasComment) ? this.comment.ToString () : null; }
|
||||
}
|
||||
|
||||
/// <include file='IniReader.xml' path='//Property[@name="LineNumber"]/docs/*' />
|
||||
public int LineNumber
|
||||
{
|
||||
get { return lineNumber; }
|
||||
}
|
||||
|
||||
/// <include file='IniReader.xml' path='//Property[@name="LinePosition"]/docs/*' />
|
||||
public int LinePosition
|
||||
{
|
||||
get { return column; }
|
||||
}
|
||||
|
||||
/// <include file='IniReader.xml' path='//Property[@name="IgnoreComments"]/docs/*' />
|
||||
public bool IgnoreComments
|
||||
{
|
||||
get { return ignoreComments; }
|
||||
set { ignoreComments = value; }
|
||||
}
|
||||
|
||||
/// <include file='IniReader.xml' path='//Property[@name="ReadState"]/docs/*' />
|
||||
public IniReadState ReadState
|
||||
{
|
||||
get { return readState; }
|
||||
}
|
||||
|
||||
/// <include file='IniReader.xml' path='//Property[@name="LineContinuation"]/docs/*' />
|
||||
public bool LineContinuation
|
||||
{
|
||||
get { return lineContinuation; }
|
||||
set { lineContinuation = value; }
|
||||
}
|
||||
|
||||
/// <include file='IniReader.xml' path='//Property[@name="AcceptCommentAfterKey"]/docs/*' />
|
||||
public bool AcceptCommentAfterKey
|
||||
{
|
||||
get { return acceptCommentAfterKey; }
|
||||
set { acceptCommentAfterKey = value; }
|
||||
}
|
||||
|
||||
/// <include file='IniReader.xml' path='//Property[@name="AcceptNoAssignmentOperator"]/docs/*' />
|
||||
public bool AcceptNoAssignmentOperator
|
||||
{
|
||||
get { return acceptNoAssignmentOperator; }
|
||||
set { acceptNoAssignmentOperator = value; }
|
||||
}
|
||||
|
||||
/// <include file='IniReader.xml' path='//Property[@name="ConsumeAllKeyText"]/docs/*' />
|
||||
public bool ConsumeAllKeyText
|
||||
{
|
||||
get { return consumeAllKeyText; }
|
||||
set { consumeAllKeyText = value; }
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region Constructors
|
||||
/// <include file='IniReader.xml' path='//Constructor[@name="ConstructorPath"]/docs/*' />
|
||||
public IniReader (string filePath)
|
||||
{
|
||||
textReader = new StreamReader (filePath);
|
||||
}
|
||||
|
||||
/// <include file='IniReader.xml' path='//Constructor[@name="ConstructorTextReader"]/docs/*' />
|
||||
public IniReader (TextReader reader)
|
||||
{
|
||||
textReader = reader;
|
||||
}
|
||||
|
||||
/// <include file='IniReader.xml' path='//Constructor[@name="ConstructorStream"]/docs/*' />
|
||||
public IniReader (Stream stream)
|
||||
: this (new StreamReader (stream))
|
||||
{
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region Public methods
|
||||
/// <include file='IniReader.xml' path='//Method[@name="Read"]/docs/*' />
|
||||
public bool Read ()
|
||||
{
|
||||
bool result = false;
|
||||
|
||||
if (readState != IniReadState.EndOfFile
|
||||
|| readState != IniReadState.Closed) {
|
||||
readState = IniReadState.Interactive;
|
||||
result = ReadNext ();
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/// <include file='IniReader.xml' path='//Method[@name="MoveToNextSection"]/docs/*' />
|
||||
public bool MoveToNextSection ()
|
||||
{
|
||||
bool result = false;
|
||||
|
||||
while (true)
|
||||
{
|
||||
result = Read ();
|
||||
|
||||
if (iniType == IniType.Section || !result) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/// <include file='IniReader.xml' path='//Method[@name="MoveToNextKey"]/docs/*' />
|
||||
public bool MoveToNextKey ()
|
||||
{
|
||||
bool result = false;
|
||||
|
||||
while (true)
|
||||
{
|
||||
result = Read ();
|
||||
|
||||
if (iniType == IniType.Section) {
|
||||
result = false;
|
||||
break;
|
||||
}
|
||||
if (iniType == IniType.Key || !result) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/// <include file='IniReader.xml' path='//Method[@name="Close"]/docs/*' />
|
||||
public void Close ()
|
||||
{
|
||||
Reset ();
|
||||
readState = IniReadState.Closed;
|
||||
|
||||
if (textReader != null) {
|
||||
textReader.Close ();
|
||||
}
|
||||
}
|
||||
|
||||
/// <include file='IniReader.xml' path='//Method[@name="Dispose"]/docs/*' />
|
||||
public void Dispose ()
|
||||
{
|
||||
Dispose (true);
|
||||
}
|
||||
|
||||
/// <include file='IniReader.xml' path='//Method[@name="GetCommentDelimiters"]/docs/*' />
|
||||
public char[] GetCommentDelimiters ()
|
||||
{
|
||||
char[] result = new char[commentDelimiters.Length];
|
||||
Array.Copy (commentDelimiters, 0, result, 0, commentDelimiters.Length);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/// <include file='IniReader.xml' path='//Method[@name="SetCommentDelimiters"]/docs/*' />
|
||||
public void SetCommentDelimiters (char[] delimiters)
|
||||
{
|
||||
if (delimiters.Length < 1) {
|
||||
throw new ArgumentException ("Must supply at least one delimiter");
|
||||
}
|
||||
|
||||
commentDelimiters = delimiters;
|
||||
}
|
||||
|
||||
/// <include file='IniReader.xml' path='//Method[@name="GetAssignDelimiters"]/docs/*' />
|
||||
public char[] GetAssignDelimiters ()
|
||||
{
|
||||
char[] result = new char[assignDelimiters.Length];
|
||||
Array.Copy (assignDelimiters, 0, result, 0, assignDelimiters.Length);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/// <include file='IniReader.xml' path='//Method[@name="SetAssignDelimiters"]/docs/*' />
|
||||
public void SetAssignDelimiters (char[] delimiters)
|
||||
{
|
||||
if (delimiters.Length < 1) {
|
||||
throw new ArgumentException ("Must supply at least one delimiter");
|
||||
}
|
||||
|
||||
assignDelimiters = delimiters;
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region Protected methods
|
||||
/// <include file='IniReader.xml' path='//Method[@name="DisposeBoolean"]/docs/*' />
|
||||
protected virtual void Dispose (bool disposing)
|
||||
{
|
||||
if (!disposed) {
|
||||
textReader.Close ();
|
||||
disposed = true;
|
||||
|
||||
if (disposing) {
|
||||
GC.SuppressFinalize (this);
|
||||
}
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region Private methods
|
||||
/// <summary>
|
||||
/// Destructor.
|
||||
/// </summary>
|
||||
~IniReader ()
|
||||
{
|
||||
Dispose (false);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Resets all of the current INI line data.
|
||||
/// </summary>
|
||||
private void Reset ()
|
||||
{
|
||||
this.name.Remove (0, this.name.Length);
|
||||
this.value.Remove (0, this.value.Length);
|
||||
this.comment.Remove (0, this.comment.Length);
|
||||
iniType = IniType.Empty;
|
||||
hasComment = false;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Reads the next INI line item.
|
||||
/// </summary>
|
||||
private bool ReadNext ()
|
||||
{
|
||||
bool result = true;
|
||||
int ch = PeekChar ();
|
||||
Reset ();
|
||||
|
||||
if (IsComment (ch)) {
|
||||
iniType = IniType.Empty;
|
||||
ReadChar (); // consume comment character
|
||||
ReadComment ();
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
switch (ch)
|
||||
{
|
||||
case ' ':
|
||||
case '\t':
|
||||
case '\r':
|
||||
SkipWhitespace ();
|
||||
ReadNext ();
|
||||
break;
|
||||
case '\n':
|
||||
ReadChar ();
|
||||
break;
|
||||
case '[':
|
||||
ReadSection ();
|
||||
break;
|
||||
case -1:
|
||||
readState = IniReadState.EndOfFile;
|
||||
result = false;
|
||||
break;
|
||||
default:
|
||||
ReadKey ();
|
||||
break;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Reads a comment. Must start after the comment delimiter.
|
||||
/// </summary>
|
||||
private void ReadComment ()
|
||||
{
|
||||
int ch = -1;
|
||||
SkipWhitespace ();
|
||||
hasComment = true;
|
||||
|
||||
do
|
||||
{
|
||||
ch = ReadChar ();
|
||||
this.comment.Append ((char)ch);
|
||||
} while (!EndOfLine (ch));
|
||||
|
||||
RemoveTrailingWhitespace (this.comment);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Removes trailing whitespace from a StringBuilder.
|
||||
/// </summary>
|
||||
private void RemoveTrailingWhitespace (StringBuilder builder)
|
||||
{
|
||||
string temp = builder.ToString ();
|
||||
|
||||
builder.Remove (0, builder.Length);
|
||||
builder.Append (temp.TrimEnd (null));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Reads a key.
|
||||
/// </summary>
|
||||
private void ReadKey ()
|
||||
{
|
||||
int ch = -1;
|
||||
iniType = IniType.Key;
|
||||
|
||||
while (true)
|
||||
{
|
||||
ch = PeekChar ();
|
||||
|
||||
if (IsAssign (ch)) {
|
||||
ReadChar ();
|
||||
break;
|
||||
}
|
||||
|
||||
if (EndOfLine (ch)) {
|
||||
if (acceptNoAssignmentOperator) {
|
||||
break;
|
||||
}
|
||||
throw new IniException (this,
|
||||
String.Format ("Expected assignment operator ({0})",
|
||||
assignDelimiters[0]));
|
||||
}
|
||||
|
||||
this.name.Append ((char)ReadChar ());
|
||||
}
|
||||
|
||||
ReadKeyValue ();
|
||||
SearchForComment ();
|
||||
RemoveTrailingWhitespace (this.name);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Reads the value of a key.
|
||||
/// </summary>
|
||||
private void ReadKeyValue ()
|
||||
{
|
||||
int ch = -1;
|
||||
bool foundQuote = false;
|
||||
int characters = 0;
|
||||
SkipWhitespace ();
|
||||
|
||||
while (true)
|
||||
{
|
||||
ch = PeekChar ();
|
||||
|
||||
if (!IsWhitespace (ch)) {
|
||||
characters++;
|
||||
}
|
||||
|
||||
if (!this.ConsumeAllKeyText && ch == '"') {
|
||||
ReadChar ();
|
||||
|
||||
if (!foundQuote && characters == 1) {
|
||||
foundQuote = true;
|
||||
continue;
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (foundQuote && EndOfLine (ch)) {
|
||||
throw new IniException (this, "Expected closing quote (\")");
|
||||
}
|
||||
|
||||
// Handle line continuation
|
||||
if (lineContinuation && ch == '\\')
|
||||
{
|
||||
StringBuilder buffer = new StringBuilder ();
|
||||
buffer.Append ((char)ReadChar ()); // append '\'
|
||||
|
||||
while (PeekChar () != '\n' && IsWhitespace (PeekChar ()))
|
||||
{
|
||||
if (PeekChar () != '\r') {
|
||||
buffer.Append ((char)ReadChar ());
|
||||
} else {
|
||||
ReadChar (); // consume '\r'
|
||||
}
|
||||
}
|
||||
|
||||
if (PeekChar () == '\n') {
|
||||
// continue reading key value on next line
|
||||
ReadChar ();
|
||||
continue;
|
||||
} else {
|
||||
// Replace consumed characters
|
||||
this.value.Append (buffer.ToString ());
|
||||
}
|
||||
}
|
||||
|
||||
if (!this.ConsumeAllKeyText) {
|
||||
// If accepting comments then don't consume as key value
|
||||
if (acceptCommentAfterKey && IsComment (ch) && !foundQuote) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Always break at end of line
|
||||
if (EndOfLine (ch)) {
|
||||
break;
|
||||
}
|
||||
|
||||
this.value.Append ((char)ReadChar ());
|
||||
}
|
||||
|
||||
if (!foundQuote) {
|
||||
RemoveTrailingWhitespace (this.value);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Reads an INI section.
|
||||
/// </summary>
|
||||
private void ReadSection ()
|
||||
{
|
||||
int ch = -1;
|
||||
iniType = IniType.Section;
|
||||
ch = ReadChar (); // consume "["
|
||||
|
||||
while (true)
|
||||
{
|
||||
ch = PeekChar ();
|
||||
if (ch == ']') {
|
||||
break;
|
||||
}
|
||||
if (EndOfLine (ch)) {
|
||||
throw new IniException (this, "Expected section end (])");
|
||||
}
|
||||
|
||||
this.name.Append ((char)ReadChar ());
|
||||
}
|
||||
|
||||
ConsumeToEnd (); // all after '[' is garbage
|
||||
RemoveTrailingWhitespace (this.name);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks for a comment.
|
||||
/// </summary>
|
||||
private void SearchForComment ()
|
||||
{
|
||||
int ch = ReadChar ();
|
||||
|
||||
while (!EndOfLine (ch))
|
||||
{
|
||||
if (IsComment (ch)) {
|
||||
if (ignoreComments) {
|
||||
ConsumeToEnd ();
|
||||
} else {
|
||||
ReadComment ();
|
||||
}
|
||||
break;
|
||||
}
|
||||
ch = ReadChar ();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Consumes all data until the end of a line.
|
||||
/// </summary>
|
||||
private void ConsumeToEnd ()
|
||||
{
|
||||
int ch = -1;
|
||||
|
||||
do
|
||||
{
|
||||
ch = ReadChar ();
|
||||
} while (!EndOfLine (ch));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns and consumes the next character from the stream.
|
||||
/// </summary>
|
||||
private int ReadChar ()
|
||||
{
|
||||
int result = textReader.Read ();
|
||||
|
||||
if (result == '\n') {
|
||||
lineNumber++;
|
||||
column = 1;
|
||||
} else {
|
||||
column++;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns the next upcoming character from the stream.
|
||||
/// </summary>
|
||||
private int PeekChar ()
|
||||
{
|
||||
return textReader.Peek ();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns true if a comment character is found.
|
||||
/// </summary>
|
||||
private bool IsComment (int ch)
|
||||
{
|
||||
return HasCharacter (commentDelimiters, ch);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns true if character is an assign character.
|
||||
/// </summary>
|
||||
private bool IsAssign (int ch)
|
||||
{
|
||||
return HasCharacter (assignDelimiters, ch);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns true if the character is found in the given array.
|
||||
/// </summary>
|
||||
private bool HasCharacter (char[] characters, int ch)
|
||||
{
|
||||
bool result = false;
|
||||
|
||||
for (int i = 0; i < characters.Length; i++)
|
||||
{
|
||||
if (ch == characters[i])
|
||||
{
|
||||
result = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns true if a value is whitespace.
|
||||
/// </summary>
|
||||
private bool IsWhitespace (int ch)
|
||||
{
|
||||
return ch == 0x20 || ch == 0x9 || ch == 0xD || ch == 0xA;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Skips all whitespace.
|
||||
/// </summary>
|
||||
private void SkipWhitespace ()
|
||||
{
|
||||
while (IsWhitespace (PeekChar ()))
|
||||
{
|
||||
if (EndOfLine (PeekChar ())) {
|
||||
break;
|
||||
}
|
||||
|
||||
ReadChar ();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns true if an end of line is found. End of line
|
||||
/// includes both an end of line or end of file.
|
||||
/// </summary>
|
||||
private bool EndOfLine (int ch)
|
||||
{
|
||||
return (ch == '\n' || ch == -1);
|
||||
}
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
155
ExtensionLoader/Ini/IniSection.cs
Normal file
155
ExtensionLoader/Ini/IniSection.cs
Normal file
@@ -0,0 +1,155 @@
|
||||
#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.Collections;
|
||||
using ExtensionLoader.Util;
|
||||
|
||||
namespace ExtensionLoader.Ini
|
||||
{
|
||||
/// <include file='IniSection.xml' path='//Class[@name="IniSection"]/docs/*' />
|
||||
public class IniSection
|
||||
{
|
||||
#region Private variables
|
||||
OrderedList configList = new OrderedList ();
|
||||
string name = "";
|
||||
string comment = null;
|
||||
int commentCount = 0;
|
||||
#endregion
|
||||
|
||||
#region Constructors
|
||||
/// <include file='IniSection.xml' path='//Constructor[@name="ConstructorComment"]/docs/*' />
|
||||
public IniSection (string name, string comment)
|
||||
{
|
||||
this.name = name;
|
||||
this.comment = comment;
|
||||
}
|
||||
|
||||
/// <include file='IniSection.xml' path='//Constructor[@name="Constructor"]/docs/*' />
|
||||
public IniSection (string name)
|
||||
: this (name, null)
|
||||
{
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region Public properties
|
||||
/// <include file='IniSection.xml' path='//Property[@name="Name"]/docs/*' />
|
||||
public string Name
|
||||
{
|
||||
get { return name; }
|
||||
}
|
||||
|
||||
/// <include file='IniSection.xml' path='//Property[@name="Comment"]/docs/*' />
|
||||
public string Comment
|
||||
{
|
||||
get { return comment; }
|
||||
}
|
||||
|
||||
/// <include file='IniSection.xml' path='//Property[@name="ItemCount"]/docs/*' />
|
||||
public int ItemCount
|
||||
{
|
||||
get { return configList.Count; }
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region Public methods
|
||||
|
||||
/// <include file='IniSection.xml' path='//Method[@name="GetValue"]/docs/*' />
|
||||
public string GetValue (string key)
|
||||
{
|
||||
string result = null;
|
||||
|
||||
if (Contains (key)) {
|
||||
IniItem item = (IniItem)configList[key];
|
||||
result = item.Value;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/// <include file='IniSection.xml' path='//Method[@name="GetItem"]/docs/*' />
|
||||
public IniItem GetItem (int index)
|
||||
{
|
||||
return (IniItem)configList[index];
|
||||
}
|
||||
|
||||
/// <include file='IniSection.xml' path='//Method[@name="GetKeys"]/docs/*' />
|
||||
public string[] GetKeys ()
|
||||
{
|
||||
ArrayList list = new ArrayList ();
|
||||
IniItem item = null;
|
||||
|
||||
for (int i = 0; i < configList.Count; i++)
|
||||
{
|
||||
item = (IniItem)configList[i];
|
||||
if (item.Type == IniType.Key) {
|
||||
list.Add (item.Name);
|
||||
}
|
||||
}
|
||||
string[] result = new string[list.Count];
|
||||
list.CopyTo (result, 0);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/// <include file='IniSection.xml' path='//Method[@name="Contains"]/docs/*' />
|
||||
public bool Contains (string key)
|
||||
{
|
||||
return (configList[key] != null);
|
||||
}
|
||||
|
||||
/// <include file='IniSection.xml' path='//Method[@name="SetKeyComment"]/docs/*' />
|
||||
public void Set (string key, string value, string comment)
|
||||
{
|
||||
IniItem item = null;
|
||||
|
||||
if (Contains (key)) {
|
||||
item = (IniItem)configList[key];
|
||||
item.Value = value;
|
||||
item.Comment = comment;
|
||||
} else {
|
||||
item = new IniItem (key, value, IniType.Key, comment);
|
||||
configList.Add (key, item);
|
||||
}
|
||||
}
|
||||
|
||||
/// <include file='IniSection.xml' path='//Method[@name="SetKey"]/docs/*' />
|
||||
public void Set (string key, string value)
|
||||
{
|
||||
Set (key, value, null);
|
||||
}
|
||||
|
||||
/// <include file='IniSection.xml' path='//Method[@name="SetComment"]/docs/*' />
|
||||
public void Set (string comment)
|
||||
{
|
||||
string name = "#comment" + commentCount;
|
||||
IniItem item = new IniItem (name, null,
|
||||
IniType.Empty, comment);
|
||||
configList.Add (name, item);
|
||||
|
||||
commentCount++;
|
||||
}
|
||||
|
||||
/// <include file='IniSection.xml' path='//Method[@name="SetNoComment"]/docs/*' />
|
||||
public void Set ()
|
||||
{
|
||||
Set (null);
|
||||
}
|
||||
|
||||
/// <include file='IniSection.xml' path='//Method[@name="Remove"]/docs/*' />
|
||||
public void Remove (string key)
|
||||
{
|
||||
if (Contains (key)) {
|
||||
configList.Remove (key);
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
95
ExtensionLoader/Ini/IniSectionCollection.cs
Normal file
95
ExtensionLoader/Ini/IniSectionCollection.cs
Normal file
@@ -0,0 +1,95 @@
|
||||
#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.Collections;
|
||||
using ExtensionLoader.Util;
|
||||
|
||||
namespace ExtensionLoader.Ini
|
||||
{
|
||||
/// <include file='IniSectionCollection.xml' path='//Class[@name="IniSectionCollection"]/docs/*' />
|
||||
public class IniSectionCollection : ICollection, IEnumerable
|
||||
{
|
||||
#region Private variables
|
||||
OrderedList list = new OrderedList ();
|
||||
#endregion
|
||||
|
||||
#region Public properties
|
||||
/// <include file='IniSectionCollection.xml' path='//Property[@name="ItemIndex"]/docs/*' />
|
||||
public IniSection this[int index]
|
||||
{
|
||||
get { return (IniSection)list[index]; }
|
||||
}
|
||||
|
||||
/// <include file='IniSectionCollection.xml' path='//Property[@name="ItemName"]/docs/*' />
|
||||
public IniSection this[string configName]
|
||||
{
|
||||
get { return (IniSection)list[configName]; }
|
||||
}
|
||||
|
||||
/// <include file='IniSectionCollection.xml' path='//Property[@name="Count"]/docs/*' />
|
||||
public int Count
|
||||
{
|
||||
get { return list.Count; }
|
||||
}
|
||||
|
||||
/// <include file='IniSectionCollection.xml' path='//Property[@name="SyncRoot"]/docs/*' />
|
||||
public object SyncRoot
|
||||
{
|
||||
get { return list.SyncRoot; }
|
||||
}
|
||||
|
||||
/// <include file='IniSectionCollection.xml' path='//Property[@name="IsSynchronized"]/docs/*' />
|
||||
public bool IsSynchronized
|
||||
{
|
||||
get { return list.IsSynchronized; }
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region Public methods
|
||||
/// <include file='IniSectionCollection.xml' path='//Method[@name="Add"]/docs/*' />
|
||||
public void Add (IniSection section)
|
||||
{
|
||||
if (list.Contains (section)) {
|
||||
throw new ArgumentException ("IniSection already exists");
|
||||
}
|
||||
|
||||
list.Add (section.Name, section);
|
||||
}
|
||||
|
||||
/// <include file='IniSectionCollection.xml' path='//Method[@name="Remove"]/docs/*' />
|
||||
public void Remove (string config)
|
||||
{
|
||||
list.Remove (config);
|
||||
}
|
||||
|
||||
/// <include file='IniSectionCollection.xml' path='//Method[@name="CopyTo"]/docs/*' />
|
||||
public void CopyTo (Array array, int index)
|
||||
{
|
||||
list.CopyTo (array, index);
|
||||
}
|
||||
|
||||
/// <include file='IniSectionCollection.xml' path='//Method[@name="CopyToStrong"]/docs/*' />
|
||||
public void CopyTo (IniSection[] array, int index)
|
||||
{
|
||||
((ICollection)list).CopyTo (array, index);
|
||||
}
|
||||
|
||||
/// <include file='IniSectionCollection.xml' path='//Method[@name="GetEnumerator"]/docs/*' />
|
||||
public IEnumerator GetEnumerator ()
|
||||
{
|
||||
return list.GetEnumerator ();
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region Private methods
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
308
ExtensionLoader/Ini/IniWriter.cs
Normal file
308
ExtensionLoader/Ini/IniWriter.cs
Normal file
@@ -0,0 +1,308 @@
|
||||
#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.Text;
|
||||
|
||||
namespace ExtensionLoader.Ini
|
||||
{
|
||||
#region IniWriteState enumeration
|
||||
/// <include file='IniWriter.xml' path='//Enum[@name="IniWriteState"]/docs/*' />
|
||||
public enum IniWriteState : int
|
||||
{
|
||||
/// <include file='IniWriter.xml' path='//Enum[@name="IniWriteState"]/Value[@name="Start"]/docs/*' />
|
||||
Start,
|
||||
/// <include file='IniWriter.xml' path='//Enum[@name="IniWriteState"]/Value[@name="BeforeFirstSection"]/docs/*' />
|
||||
BeforeFirstSection,
|
||||
/// <include file='IniWriter.xml' path='//Enum[@name="IniWriteState"]/Value[@name="Section"]/docs/*' />
|
||||
Section,
|
||||
/// <include file='IniWriter.xml' path='//Enum[@name="IniWriteState"]/Value[@name="Closed"]/docs/*' />
|
||||
Closed
|
||||
};
|
||||
#endregion
|
||||
|
||||
/// <include file='IniWriter.xml' path='//Class[@name="IniWriter"]/docs/*' />
|
||||
public class IniWriter : IDisposable
|
||||
{
|
||||
#region Private variables
|
||||
int indentation = 0;
|
||||
bool useValueQuotes = false;
|
||||
IniWriteState writeState = IniWriteState.Start;
|
||||
char commentDelimiter = ';';
|
||||
char assignDelimiter = '=';
|
||||
TextWriter textWriter = null;
|
||||
string eol = "\r\n";
|
||||
StringBuilder indentationBuffer = new StringBuilder ();
|
||||
Stream baseStream = null;
|
||||
bool disposed = false;
|
||||
#endregion
|
||||
|
||||
#region Public properties
|
||||
/// <include file='IniWriter.xml' path='//Property[@name="Indentation"]/docs/*' />
|
||||
public int Indentation
|
||||
{
|
||||
get { return indentation; }
|
||||
set
|
||||
{
|
||||
if (value < 0)
|
||||
throw new ArgumentException ("Negative values are illegal");
|
||||
|
||||
indentation = value;
|
||||
indentationBuffer.Remove(0, indentationBuffer.Length);
|
||||
for (int i = 0; i < value; i++)
|
||||
indentationBuffer.Append (' ');
|
||||
}
|
||||
}
|
||||
|
||||
/// <include file='IniWriter.xml' path='//Property[@name="UseValueQuotes"]/docs/*' />
|
||||
public bool UseValueQuotes
|
||||
{
|
||||
get { return useValueQuotes; }
|
||||
set { useValueQuotes = value; }
|
||||
}
|
||||
|
||||
/// <include file='IniWriter.xml' path='//Property[@name="WriteState"]/docs/*' />
|
||||
public IniWriteState WriteState
|
||||
{
|
||||
get { return writeState; }
|
||||
}
|
||||
|
||||
/// <include file='IniWriter.xml' path='//Property[@name="CommentDelimiter"]/docs/*' />
|
||||
public char CommentDelimiter
|
||||
{
|
||||
get { return commentDelimiter; }
|
||||
set { commentDelimiter = value; }
|
||||
}
|
||||
|
||||
/// <include file='IniWriter.xml' path='//Property[@name="AssignDelimiter"]/docs/*' />
|
||||
public char AssignDelimiter
|
||||
{
|
||||
get { return assignDelimiter; }
|
||||
set { assignDelimiter = value; }
|
||||
}
|
||||
|
||||
/// <include file='IniWriter.xml' path='//Property[@name="BaseStream"]/docs/*' />
|
||||
public Stream BaseStream
|
||||
{
|
||||
get { return baseStream; }
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region Constructors
|
||||
/// <include file='IniWriter.xml' path='//Constructor[@name="ConstructorPath"]/docs/*' />
|
||||
public IniWriter(string filePath)
|
||||
: this (new FileStream (filePath, FileMode.Create, FileAccess.Write, FileShare.None))
|
||||
{
|
||||
}
|
||||
|
||||
/// <include file='IniWriter.xml' path='//Constructor[@name="ConstructorTextWriter"]/docs/*' />
|
||||
public IniWriter (TextWriter writer)
|
||||
{
|
||||
textWriter = writer;
|
||||
StreamWriter streamWriter = writer as StreamWriter;
|
||||
if (streamWriter != null) {
|
||||
baseStream = streamWriter.BaseStream;
|
||||
}
|
||||
}
|
||||
|
||||
/// <include file='IniWriter.xml' path='//Constructor[@name="ConstructorStream"]/docs/*' />
|
||||
public IniWriter (Stream stream)
|
||||
: this (new StreamWriter (stream))
|
||||
{
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region Public methods
|
||||
/// <include file='IniWriter.xml' path='//Method[@name="Close"]/docs/*' />
|
||||
public void Close ()
|
||||
{
|
||||
textWriter.Close ();
|
||||
writeState = IniWriteState.Closed;
|
||||
}
|
||||
|
||||
/// <include file='IniWriter.xml' path='//Method[@name="Flush"]/docs/*' />
|
||||
public void Flush ()
|
||||
{
|
||||
textWriter.Flush ();
|
||||
}
|
||||
|
||||
/// <include file='IniWriter.xml' path='//Method[@name="ToString"]/docs/*' />
|
||||
public override string ToString ()
|
||||
{
|
||||
return textWriter.ToString ();
|
||||
}
|
||||
|
||||
/// <include file='IniWriter.xml' path='//Method[@name="WriteSection"]/docs/*' />
|
||||
public void WriteSection (string section)
|
||||
{
|
||||
ValidateState ();
|
||||
writeState = IniWriteState.Section;
|
||||
WriteLine ("[" + section + "]");
|
||||
}
|
||||
|
||||
/// <include file='IniWriter.xml' path='//Method[@name="WriteSectionComment"]/docs/*' />
|
||||
public void WriteSection (string section, string comment)
|
||||
{
|
||||
ValidateState ();
|
||||
writeState = IniWriteState.Section;
|
||||
WriteLine ("[" + section + "]" + Comment(comment));
|
||||
}
|
||||
|
||||
/// <include file='IniWriter.xml' path='//Method[@name="WriteKey"]/docs/*' />
|
||||
public void WriteKey (string key, string value)
|
||||
{
|
||||
ValidateStateKey ();
|
||||
WriteLine (key + " " + assignDelimiter + " " + GetKeyValue (value));
|
||||
}
|
||||
|
||||
/// <include file='IniWriter.xml' path='//Method[@name="WriteKeyComment"]/docs/*' />
|
||||
public void WriteKey (string key, string value, string comment)
|
||||
{
|
||||
ValidateStateKey ();
|
||||
WriteLine (key + " " + assignDelimiter + " " + GetKeyValue (value) + Comment (comment));
|
||||
}
|
||||
|
||||
/// <include file='IniWriter.xml' path='//Method[@name="WriteEmpty"]/docs/*' />
|
||||
public void WriteEmpty ()
|
||||
{
|
||||
ValidateState ();
|
||||
if (writeState == IniWriteState.Start) {
|
||||
writeState = IniWriteState.BeforeFirstSection;
|
||||
}
|
||||
WriteLine ("");
|
||||
}
|
||||
|
||||
/// <include file='IniWriter.xml' path='//Method[@name="WriteEmptyComment"]/docs/*' />
|
||||
public void WriteEmpty (string comment)
|
||||
{
|
||||
ValidateState ();
|
||||
if (writeState == IniWriteState.Start) {
|
||||
writeState = IniWriteState.BeforeFirstSection;
|
||||
}
|
||||
if (comment == null) {
|
||||
WriteLine ("");
|
||||
} else {
|
||||
WriteLine (commentDelimiter + " " + comment);
|
||||
}
|
||||
}
|
||||
|
||||
/// <include file='IniWriter.xml' path='//Method[@name="Dispose"]/docs/*' />
|
||||
public void Dispose ()
|
||||
{
|
||||
Dispose (true);
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region Protected methods
|
||||
/// <include file='IniWriter.xml' path='//Method[@name="DisposeBoolean"]/docs/*' />
|
||||
protected virtual void Dispose (bool disposing)
|
||||
{
|
||||
if (!disposed)
|
||||
{
|
||||
textWriter.Close ();
|
||||
baseStream.Close ();
|
||||
disposed = true;
|
||||
|
||||
if (disposing)
|
||||
{
|
||||
GC.SuppressFinalize (this);
|
||||
}
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region Private methods
|
||||
/// <summary>
|
||||
/// Destructor.
|
||||
/// </summary>
|
||||
~IniWriter ()
|
||||
{
|
||||
Dispose (false);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns the value of a key.
|
||||
/// </summary>
|
||||
private string GetKeyValue (string text)
|
||||
{
|
||||
string result;
|
||||
|
||||
if (useValueQuotes) {
|
||||
result = MassageValue ('"' + text + '"');
|
||||
} else {
|
||||
result = MassageValue (text);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Validates whether a key can be written.
|
||||
/// </summary>
|
||||
private void ValidateStateKey ()
|
||||
{
|
||||
ValidateState ();
|
||||
|
||||
switch (writeState)
|
||||
{
|
||||
case IniWriteState.BeforeFirstSection:
|
||||
case IniWriteState.Start:
|
||||
throw new InvalidOperationException ("The WriteState is not Section");
|
||||
case IniWriteState.Closed:
|
||||
throw new InvalidOperationException ("The writer is closed");
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Validates the state to determine if the item can be written.
|
||||
/// </summary>
|
||||
private void ValidateState ()
|
||||
{
|
||||
if (writeState == IniWriteState.Closed) {
|
||||
throw new InvalidOperationException ("The writer is closed");
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns a formatted comment.
|
||||
/// </summary>
|
||||
private string Comment (string text)
|
||||
{
|
||||
return (text == null) ? "" : (" " + commentDelimiter + " " + text);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Writes data to the writer.
|
||||
/// </summary>
|
||||
private void Write (string value)
|
||||
{
|
||||
textWriter.Write (indentationBuffer.ToString () + value);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Writes a full line to the writer.
|
||||
/// </summary>
|
||||
private void WriteLine (string value)
|
||||
{
|
||||
Write (value + eol);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Fixes the incoming value to prevent illegal characters from
|
||||
/// hurting the integrity of the INI file.
|
||||
/// </summary>
|
||||
private string MassageValue (string text)
|
||||
{
|
||||
return text.Replace ("\n", "");
|
||||
}
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
147
ExtensionLoader/Nini/Config/AliasText.cs
Normal file
147
ExtensionLoader/Nini/Config/AliasText.cs
Normal file
@@ -0,0 +1,147 @@
|
||||
#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.Collections;
|
||||
|
||||
namespace Nini.Config
|
||||
{
|
||||
/// <include file='AliasText.xml' path='//Class[@name="AliasText"]/docs/*' />
|
||||
public class AliasText
|
||||
{
|
||||
#region Private variables
|
||||
Hashtable intAlias = null;
|
||||
Hashtable booleanAlias = null;
|
||||
#endregion
|
||||
|
||||
#region Constructors
|
||||
/// <include file='AliasText.xml' path='//Constructor[@name="AliasText"]/docs/*' />
|
||||
public AliasText ()
|
||||
{
|
||||
intAlias = InsensitiveHashtable ();
|
||||
booleanAlias = InsensitiveHashtable ();
|
||||
DefaultAliasLoad ();
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region Public methods
|
||||
/// <include file='AliasText.xml' path='//Method[@name="AddAliasInt"]/docs/*' />
|
||||
public void AddAlias (string key, string alias, int value)
|
||||
{
|
||||
if (intAlias.Contains (key)) {
|
||||
Hashtable keys = (Hashtable)intAlias[key];
|
||||
|
||||
keys[alias] = value;
|
||||
} else {
|
||||
Hashtable keys = InsensitiveHashtable ();
|
||||
keys[alias] = value;
|
||||
intAlias.Add (key, keys);
|
||||
}
|
||||
}
|
||||
|
||||
/// <include file='AliasText.xml' path='//Method[@name="AddAliasBoolean"]/docs/*' />
|
||||
public void AddAlias (string alias, bool value)
|
||||
{
|
||||
booleanAlias[alias] = value;
|
||||
}
|
||||
|
||||
#if (NET_COMPACT_1_0)
|
||||
#else
|
||||
/// <include file='AliasText.xml' path='//Method[@name="AddAliasEnum"]/docs/*' />
|
||||
public void AddAlias (string key, Enum enumAlias)
|
||||
{
|
||||
SetAliasTypes (key, enumAlias);
|
||||
}
|
||||
#endif
|
||||
|
||||
/// <include file='AliasText.xml' path='//Method[@name="ContainsBoolean"]/docs/*' />
|
||||
public bool ContainsBoolean (string key)
|
||||
{
|
||||
return booleanAlias.Contains (key);
|
||||
}
|
||||
|
||||
/// <include file='AliasText.xml' path='//Method[@name="ContainsInt"]/docs/*' />
|
||||
public bool ContainsInt (string key, string alias)
|
||||
{
|
||||
bool result = false;
|
||||
|
||||
if (intAlias.Contains (key)) {
|
||||
Hashtable keys = (Hashtable)intAlias[key];
|
||||
result = (keys.Contains (alias));
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/// <include file='AliasText.xml' path='//Method[@name="GetBoolean"]/docs/*' />
|
||||
public bool GetBoolean (string key)
|
||||
{
|
||||
if (!booleanAlias.Contains (key)) {
|
||||
throw new ArgumentException ("Alias does not exist for text");
|
||||
}
|
||||
|
||||
return (bool)booleanAlias[key];
|
||||
}
|
||||
|
||||
/// <include file='AliasText.xml' path='//Method[@name="GetInt"]/docs/*' />
|
||||
public int GetInt (string key, string alias)
|
||||
{
|
||||
if (!intAlias.Contains (key)) {
|
||||
throw new ArgumentException ("Alias does not exist for key");
|
||||
}
|
||||
|
||||
Hashtable keys = (Hashtable)intAlias[key];
|
||||
|
||||
if (!keys.Contains (alias)) {
|
||||
throw new ArgumentException ("Config value does not match a " +
|
||||
"supplied alias");
|
||||
}
|
||||
|
||||
return (int)keys[alias];
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region Private methods
|
||||
/// <summary>
|
||||
/// Loads the default alias values.
|
||||
/// </summary>
|
||||
private void DefaultAliasLoad ()
|
||||
{
|
||||
AddAlias("true", true);
|
||||
AddAlias("false", false);
|
||||
}
|
||||
|
||||
#if (NET_COMPACT_1_0)
|
||||
#else
|
||||
/// <summary>
|
||||
/// Extracts and sets the alias types from an enumeration.
|
||||
/// </summary>
|
||||
private void SetAliasTypes (string key, Enum enumAlias)
|
||||
{
|
||||
string[] names = Enum.GetNames (enumAlias.GetType ());
|
||||
int[] values = (int[])Enum.GetValues (enumAlias.GetType ());
|
||||
|
||||
for (int i = 0; i < names.Length; i++)
|
||||
{
|
||||
AddAlias (key, names[i], values[i]);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
/// <summary>
|
||||
/// Returns a case insensitive hashtable.
|
||||
/// </summary>
|
||||
private Hashtable InsensitiveHashtable ()
|
||||
{
|
||||
return new Hashtable (StringComparer.OrdinalIgnoreCase);
|
||||
}
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
422
ExtensionLoader/Nini/Config/ConfigBase.cs
Normal file
422
ExtensionLoader/Nini/Config/ConfigBase.cs
Normal file
@@ -0,0 +1,422 @@
|
||||
#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.Collections;
|
||||
using System.Globalization;
|
||||
using Nini.Util;
|
||||
|
||||
namespace Nini.Config
|
||||
{
|
||||
#region ConfigKeyEventArgs class
|
||||
/// <include file='ConfigKeyEventArgs.xml' path='//Delegate[@name="ConfigKeyEventHandler"]/docs/*' />
|
||||
public delegate void ConfigKeyEventHandler (object sender, ConfigKeyEventArgs e);
|
||||
|
||||
/// <include file='ConfigEventArgs.xml' path='//Class[@name="ConfigEventArgs"]/docs/*' />
|
||||
public class ConfigKeyEventArgs : EventArgs
|
||||
{
|
||||
string keyName = null;
|
||||
string keyValue = null;
|
||||
|
||||
/// <include file='ConfigEventArgs.xml' path='//Constructor[@name="Constructor"]/docs/*' />
|
||||
public ConfigKeyEventArgs (string keyName, string keyValue)
|
||||
{
|
||||
this.keyName = keyName;
|
||||
this.keyValue = keyValue;
|
||||
}
|
||||
|
||||
/// <include file='ConfigEventArgs.xml' path='//Property[@name="KeyName"]/docs/*' />
|
||||
public string KeyName
|
||||
{
|
||||
get { return keyName; }
|
||||
}
|
||||
|
||||
/// <include file='ConfigEventArgs.xml' path='//Property[@name="KeyValue"]/docs/*' />
|
||||
public string KeyValue
|
||||
{
|
||||
get { return keyValue; }
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
|
||||
/// <include file='IConfig.xml' path='//Interface[@name="IConfig"]/docs/*' />
|
||||
public class ConfigBase : IConfig
|
||||
{
|
||||
#region Private variables
|
||||
string configName = null;
|
||||
IConfigSource configSource = null;
|
||||
AliasText aliasText = null;
|
||||
IFormatProvider format = NumberFormatInfo.CurrentInfo;
|
||||
#endregion
|
||||
|
||||
#region Protected variables
|
||||
protected OrderedList keys = new OrderedList ();
|
||||
#endregion
|
||||
|
||||
#region Constructors
|
||||
/// <include file='ConfigBase.xml' path='//Constructor[@name="ConfigBase"]/docs/*' />
|
||||
public ConfigBase (string name, IConfigSource source)
|
||||
{
|
||||
configName = name;
|
||||
configSource = source;
|
||||
aliasText = new AliasText ();
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region Public properties
|
||||
/// <include file='IConfig.xml' path='//Property[@name="Name"]/docs/*' />
|
||||
public string Name
|
||||
{
|
||||
get { return configName; }
|
||||
set {
|
||||
if (configName != value) {
|
||||
Rename (value);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <include file='IConfig.xml' path='//Property[@name="ConfigSource"]/docs/*' />
|
||||
public IConfigSource ConfigSource
|
||||
{
|
||||
get { return configSource; }
|
||||
}
|
||||
|
||||
/// <include file='IConfig.xml' path='//Property[@name="Alias"]/docs/*' />
|
||||
public AliasText Alias
|
||||
{
|
||||
get { return aliasText; }
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region Public methods
|
||||
/// <include file='IConfig.xml' path='//Method[@name="Contains"]/docs/*' />
|
||||
public bool Contains (string key)
|
||||
{
|
||||
return (Get (key) != null);
|
||||
}
|
||||
|
||||
/// <include file='IConfig.xml' path='//Method[@name="Get"]/docs/*' />
|
||||
public virtual string Get (string key)
|
||||
{
|
||||
string result = null;
|
||||
|
||||
if (keys.Contains (key)) {
|
||||
result = keys[key].ToString ();
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/// <include file='IConfig.xml' path='//Method[@name="GetDefault"]/docs/*' />
|
||||
public string Get (string key, string defaultValue)
|
||||
{
|
||||
string result = Get (key);
|
||||
|
||||
return (result == null) ? defaultValue : result;
|
||||
}
|
||||
|
||||
/// <include file='IConfig.xml' path='//Method[@name="GetExpanded"]/docs/*' />
|
||||
public string GetExpanded (string key)
|
||||
{
|
||||
return this.ConfigSource.GetExpanded(this, key);
|
||||
}
|
||||
|
||||
/// <include file='IConfig.xml' path='//Method[@name="Get"]/docs/*' />
|
||||
public string GetString (string key)
|
||||
{
|
||||
return Get (key);
|
||||
}
|
||||
|
||||
/// <include file='IConfig.xml' path='//Method[@name="GetDefault"]/docs/*' />
|
||||
public string GetString (string key, string defaultValue)
|
||||
{
|
||||
return Get (key, defaultValue);
|
||||
}
|
||||
|
||||
/// <include file='IConfig.xml' path='//Method[@name="GetInt"]/docs/*' />
|
||||
public int GetInt (string key)
|
||||
{
|
||||
string text = Get (key);
|
||||
|
||||
if (text == null) {
|
||||
throw new ArgumentException ("Value not found: " + key);
|
||||
}
|
||||
|
||||
return Convert.ToInt32 (text, format);
|
||||
}
|
||||
|
||||
/// <include file='IConfig.xml' path='//Method[@name="GetIntAlias"]/docs/*' />
|
||||
public int GetInt (string key, bool fromAlias)
|
||||
{
|
||||
if (!fromAlias) {
|
||||
return GetInt (key);
|
||||
}
|
||||
|
||||
string result = Get (key);
|
||||
|
||||
if (result == null) {
|
||||
throw new ArgumentException ("Value not found: " + key);
|
||||
}
|
||||
|
||||
return GetIntAlias (key, result);
|
||||
}
|
||||
|
||||
/// <include file='IConfig.xml' path='//Method[@name="GetIntDefault"]/docs/*' />
|
||||
public int GetInt (string key, int defaultValue)
|
||||
{
|
||||
string result = Get (key);
|
||||
|
||||
return (result == null)
|
||||
? defaultValue
|
||||
: Convert.ToInt32 (result, format);
|
||||
}
|
||||
|
||||
/// <include file='IConfig.xml' path='//Method[@name="GetIntDefaultAlias"]/docs/*' />
|
||||
public int GetInt (string key, int defaultValue, bool fromAlias)
|
||||
{
|
||||
if (!fromAlias) {
|
||||
return GetInt (key, defaultValue);
|
||||
}
|
||||
|
||||
string result = Get (key);
|
||||
|
||||
return (result == null) ? defaultValue : GetIntAlias (key, result);
|
||||
}
|
||||
|
||||
/// <include file='IConfig.xml' path='//Method[@name="GetLong"]/docs/*' />
|
||||
public long GetLong (string key)
|
||||
{
|
||||
string text = Get (key);
|
||||
|
||||
if (text == null) {
|
||||
throw new ArgumentException ("Value not found: " + key);
|
||||
}
|
||||
|
||||
return Convert.ToInt64 (text, format);
|
||||
}
|
||||
|
||||
/// <include file='IConfig.xml' path='//Method[@name="GetLongDefault"]/docs/*' />
|
||||
public long GetLong (string key, long defaultValue)
|
||||
{
|
||||
string result = Get (key);
|
||||
|
||||
return (result == null)
|
||||
? defaultValue
|
||||
: Convert.ToInt64 (result, format);
|
||||
}
|
||||
|
||||
/// <include file='IConfig.xml' path='//Method[@name="GetBoolean"]/docs/*' />
|
||||
public bool GetBoolean (string key)
|
||||
{
|
||||
string text = Get (key);
|
||||
|
||||
if (text == null) {
|
||||
throw new ArgumentException ("Value not found: " + key);
|
||||
}
|
||||
|
||||
return GetBooleanAlias (text);
|
||||
}
|
||||
|
||||
/// <include file='IConfig.xml' path='//Method[@name="GetBooleanDefault"]/docs/*' />
|
||||
public bool GetBoolean (string key, bool defaultValue)
|
||||
{
|
||||
string text = Get (key);
|
||||
|
||||
return (text == null) ? defaultValue : GetBooleanAlias (text);
|
||||
}
|
||||
|
||||
/// <include file='IConfig.xml' path='//Method[@name="GetFloat"]/docs/*' />
|
||||
public float GetFloat (string key)
|
||||
{
|
||||
string text = Get (key);
|
||||
|
||||
if (text == null) {
|
||||
throw new ArgumentException ("Value not found: " + key);
|
||||
}
|
||||
|
||||
return Convert.ToSingle (text, format);
|
||||
}
|
||||
|
||||
/// <include file='IConfig.xml' path='//Method[@name="GetFloatDefault"]/docs/*' />
|
||||
public float GetFloat (string key, float defaultValue)
|
||||
{
|
||||
string result = Get (key);
|
||||
|
||||
return (result == null)
|
||||
? defaultValue
|
||||
: Convert.ToSingle (result, format);
|
||||
}
|
||||
|
||||
/// <include file='IConfig.xml' path='//Method[@name="GetDouble"]/docs/*' />
|
||||
public double GetDouble (string key)
|
||||
{
|
||||
string text = Get (key);
|
||||
|
||||
if (text == null) {
|
||||
throw new ArgumentException ("Value not found: " + key);
|
||||
}
|
||||
|
||||
return Convert.ToDouble (text, format);
|
||||
}
|
||||
|
||||
/// <include file='IConfig.xml' path='//Method[@name="GetDoubleDefault"]/docs/*' />
|
||||
public double GetDouble (string key, double defaultValue)
|
||||
{
|
||||
string result = Get (key);
|
||||
|
||||
return (result == null)
|
||||
? defaultValue
|
||||
: Convert.ToDouble (result, format);
|
||||
}
|
||||
|
||||
/// <include file='IConfig.xml' path='//Method[@name="GetKeys"]/docs/*' />
|
||||
public string[] GetKeys ()
|
||||
{
|
||||
string[] result = new string[keys.Keys.Count];
|
||||
|
||||
keys.Keys.CopyTo (result, 0);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/// <include file='IConfig.xml' path='//Method[@name="GetValues"]/docs/*' />
|
||||
public string[] GetValues ()
|
||||
{
|
||||
string[] result = new string[keys.Values.Count];
|
||||
|
||||
keys.Values.CopyTo (result, 0);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/// <include file='ConfigBase.xml' path='//Method[@name="Add"]/docs/*' />
|
||||
public void Add (string key, string value)
|
||||
{
|
||||
keys.Add (key, value);
|
||||
}
|
||||
|
||||
/// <include file='IConfig.xml' path='//Method[@name="Set"]/docs/*' />
|
||||
public virtual void Set (string key, object value)
|
||||
{
|
||||
if (value == null) {
|
||||
throw new ArgumentNullException ("Value cannot be null");
|
||||
}
|
||||
|
||||
if (Get (key) == null) {
|
||||
this.Add (key, value.ToString ());
|
||||
} else {
|
||||
keys[key] = value.ToString ();
|
||||
}
|
||||
|
||||
if (ConfigSource.AutoSave) {
|
||||
ConfigSource.Save ();
|
||||
}
|
||||
|
||||
OnKeySet (new ConfigKeyEventArgs (key, value.ToString ()));
|
||||
}
|
||||
|
||||
/// <include file='IConfig.xml' path='//Method[@name="Remove"]/docs/*' />
|
||||
public virtual void Remove (string key)
|
||||
{
|
||||
if (key == null) {
|
||||
throw new ArgumentNullException ("Key cannot be null");
|
||||
}
|
||||
|
||||
if (Get (key) != null) {
|
||||
string keyValue = null;
|
||||
if (KeySet != null) {
|
||||
keyValue = Get (key);
|
||||
}
|
||||
keys.Remove (key);
|
||||
|
||||
OnKeyRemoved (new ConfigKeyEventArgs (key, keyValue));
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region Public events
|
||||
/// <include file='IConfig.xml' path='//Event[@name="KeySet"]/docs/*' />
|
||||
public event ConfigKeyEventHandler KeySet;
|
||||
|
||||
/// <include file='IConfig.xml' path='//Event[@name="KeyRemoved"]/docs/*' />
|
||||
public event ConfigKeyEventHandler KeyRemoved;
|
||||
#endregion
|
||||
|
||||
#region Protected methods
|
||||
/// <include file='ConfigBase.xml' path='//Method[@name="OnKeySet"]/docs/*' />
|
||||
protected void OnKeySet (ConfigKeyEventArgs e)
|
||||
{
|
||||
if (KeySet != null) {
|
||||
KeySet (this, e);
|
||||
}
|
||||
}
|
||||
|
||||
/// <include file='ConfigBase.xml' path='//Method[@name="OnKeyRemoved"]/docs/*' />
|
||||
protected void OnKeyRemoved (ConfigKeyEventArgs e)
|
||||
{
|
||||
if (KeyRemoved != null) {
|
||||
KeyRemoved (this, e);
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region Private methods
|
||||
/// <summary>
|
||||
/// Renames the config to the new name.
|
||||
/// </summary>
|
||||
private void Rename (string name)
|
||||
{
|
||||
this.ConfigSource.Configs.Remove (this);
|
||||
configName = name;
|
||||
this.ConfigSource.Configs.Add (this);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns the integer alias first from this IConfig then
|
||||
/// the parent if there is none.
|
||||
/// </summary>
|
||||
private int GetIntAlias (string key, string alias)
|
||||
{
|
||||
int result = -1;
|
||||
|
||||
if (aliasText.ContainsInt (key, alias)) {
|
||||
result = aliasText.GetInt (key, alias);
|
||||
} else {
|
||||
result = ConfigSource.Alias.GetInt (key, alias);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns the boolean alias first from this IConfig then
|
||||
/// the parent if there is none.
|
||||
/// </summary>
|
||||
private bool GetBooleanAlias (string key)
|
||||
{
|
||||
bool result = false;
|
||||
|
||||
if (aliasText.ContainsBoolean (key)) {
|
||||
result = aliasText.GetBoolean (key);
|
||||
} else {
|
||||
if (ConfigSource.Alias.ContainsBoolean (key)) {
|
||||
result = ConfigSource.Alias.GetBoolean (key);
|
||||
} else {
|
||||
throw new ArgumentException
|
||||
("Alias value not found: " + key
|
||||
+ ". Add it to the Alias property.");
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
264
ExtensionLoader/Nini/Config/ConfigCollection.cs
Normal file
264
ExtensionLoader/Nini/Config/ConfigCollection.cs
Normal file
@@ -0,0 +1,264 @@
|
||||
#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.Collections;
|
||||
|
||||
namespace Nini.Config
|
||||
{
|
||||
#region ConfigEventHandler class
|
||||
/// <include file='ConfigEventArgs.xml' path='//Delegate[@name="ConfigEventHandler"]/docs/*' />
|
||||
public delegate void ConfigEventHandler (object sender, ConfigEventArgs e);
|
||||
|
||||
/// <include file='ConfigEventArgs.xml' path='//Class[@name="ConfigEventArgs"]/docs/*' />
|
||||
public class ConfigEventArgs : EventArgs
|
||||
{
|
||||
IConfig config = null;
|
||||
|
||||
/// <include file='ConfigEventArgs.xml' path='//Constructor[@name="ConstructorIConfig"]/docs/*' />
|
||||
public ConfigEventArgs (IConfig config)
|
||||
{
|
||||
this.config = config;
|
||||
}
|
||||
|
||||
/// <include file='ConfigEventArgs.xml' path='//Property[@name="Config"]/docs/*' />
|
||||
public IConfig Config
|
||||
{
|
||||
get { return config; }
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
|
||||
/// <include file='ConfigCollection.xml' path='//Class[@name="ConfigCollection"]/docs/*' />
|
||||
public class ConfigCollection : ICollection, IEnumerable, IList
|
||||
{
|
||||
#region Private variables
|
||||
ArrayList configList = new ArrayList ();
|
||||
ConfigSourceBase owner = null;
|
||||
#endregion
|
||||
|
||||
#region Constructors
|
||||
/// <include file='ConfigCollection.xml' path='//Constructor[@name="Constructor"]/docs/*' />
|
||||
public ConfigCollection (ConfigSourceBase owner)
|
||||
{
|
||||
this.owner = owner;
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region Public properties
|
||||
/// <include file='ConfigCollection.xml' path='//Property[@name="Count"]/docs/*' />
|
||||
public int Count
|
||||
{
|
||||
get { return configList.Count; }
|
||||
}
|
||||
|
||||
/// <include file='ConfigCollection.xml' path='//Property[@name="IsSynchronized"]/docs/*' />
|
||||
public bool IsSynchronized
|
||||
{
|
||||
get { return false; }
|
||||
}
|
||||
|
||||
/// <include file='ConfigCollection.xml' path='//Property[@name="SyncRoot"]/docs/*' />
|
||||
public object SyncRoot
|
||||
{
|
||||
get { return this; }
|
||||
}
|
||||
|
||||
/// <include file='ConfigCollection.xml' path='//Property[@name="ItemIndex"]/docs/*' />
|
||||
public IConfig this[int index]
|
||||
{
|
||||
get { return (IConfig)configList[index]; }
|
||||
}
|
||||
|
||||
/// <include file='ConfigCollection.xml' path='//Property[@name="ItemIndex"]/docs/*' />
|
||||
object IList.this[int index]
|
||||
{
|
||||
get { return configList[index]; }
|
||||
set { }
|
||||
}
|
||||
|
||||
/// <include file='ConfigCollection.xml' path='//Property[@name="ItemName"]/docs/*' />
|
||||
public IConfig this[string configName]
|
||||
{
|
||||
get
|
||||
{
|
||||
IConfig result = null;
|
||||
|
||||
foreach (IConfig config in configList)
|
||||
{
|
||||
if (config.Name == configName) {
|
||||
result = config;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
/// <include file='ConfigCollection.xml' path='//Property[@name="IsFixedSize"]/docs/*' />
|
||||
public bool IsFixedSize
|
||||
{
|
||||
get { return false; }
|
||||
}
|
||||
|
||||
/// <include file='ConfigCollection.xml' path='//Property[@name="IsReadOnly"]/docs/*' />
|
||||
public bool IsReadOnly
|
||||
{
|
||||
get { return false; }
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region Public methods
|
||||
/// <include file='ConfigCollection.xml' path='//Method[@name="Add"]/docs/*' />
|
||||
public void Add (IConfig config)
|
||||
{
|
||||
if (configList.Contains (config)) {
|
||||
throw new ArgumentException ("IConfig already exists");
|
||||
}
|
||||
IConfig existingConfig = this[config.Name];
|
||||
|
||||
if (existingConfig != null) {
|
||||
// Set all new keys
|
||||
string[] keys = config.GetKeys ();
|
||||
for (int i = 0; i < keys.Length; i++)
|
||||
{
|
||||
existingConfig.Set (keys[i], config.Get (keys[i]));
|
||||
}
|
||||
} else {
|
||||
configList.Add (config);
|
||||
OnConfigAdded (new ConfigEventArgs (config));
|
||||
}
|
||||
}
|
||||
|
||||
/// <include file='ConfigCollection.xml' path='//Method[@name="Add"]/docs/*' />
|
||||
int IList.Add (object config)
|
||||
{
|
||||
IConfig newConfig = config as IConfig;
|
||||
|
||||
if (newConfig == null) {
|
||||
throw new Exception ("Must be an IConfig");
|
||||
} else {
|
||||
this.Add (newConfig);
|
||||
return IndexOf (newConfig);
|
||||
}
|
||||
}
|
||||
|
||||
/// <include file='ConfigCollection.xml' path='//Method[@name="AddName"]/docs/*' />
|
||||
public IConfig Add (string name)
|
||||
{
|
||||
ConfigBase result = null;
|
||||
|
||||
if (this[name] == null) {
|
||||
result = new ConfigBase (name, owner);
|
||||
configList.Add (result);
|
||||
OnConfigAdded (new ConfigEventArgs (result));
|
||||
} else {
|
||||
throw new ArgumentException ("An IConfig of that name already exists");
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/// <include file='ConfigCollection.xml' path='//Method[@name="Remove"]/docs/*' />
|
||||
public void Remove (IConfig config)
|
||||
{
|
||||
configList.Remove (config);
|
||||
OnConfigRemoved (new ConfigEventArgs (config));
|
||||
}
|
||||
|
||||
/// <include file='ConfigCollection.xml' path='//Method[@name="Remove"]/docs/*' />
|
||||
public void Remove (object config)
|
||||
{
|
||||
configList.Remove (config);
|
||||
OnConfigRemoved (new ConfigEventArgs ((IConfig)config));
|
||||
}
|
||||
|
||||
/// <include file='ConfigCollection.xml' path='//Method[@name="RemoveAt"]/docs/*' />
|
||||
public void RemoveAt (int index)
|
||||
{
|
||||
IConfig config = (IConfig)configList[index];
|
||||
configList.RemoveAt (index);
|
||||
OnConfigRemoved (new ConfigEventArgs (config));
|
||||
}
|
||||
|
||||
/// <include file='ConfigCollection.xml' path='//Method[@name="Clear"]/docs/*' />
|
||||
public void Clear ()
|
||||
{
|
||||
configList.Clear ();
|
||||
}
|
||||
|
||||
/// <include file='ConfigCollection.xml' path='//Method[@name="GetEnumerator"]/docs/*' />
|
||||
public IEnumerator GetEnumerator ()
|
||||
{
|
||||
return configList.GetEnumerator ();
|
||||
}
|
||||
|
||||
/// <include file='ConfigCollection.xml' path='//Method[@name="CopyTo"]/docs/*' />
|
||||
public void CopyTo (Array array, int index)
|
||||
{
|
||||
configList.CopyTo (array, index);
|
||||
}
|
||||
|
||||
/// <include file='ConfigCollection.xml' path='//Method[@name="CopyToStrong"]/docs/*' />
|
||||
public void CopyTo (IConfig[] array, int index)
|
||||
{
|
||||
((ICollection)configList).CopyTo (array, index);
|
||||
}
|
||||
|
||||
/// <include file='ConfigCollection.xml' path='//Method[@name="Contains"]/docs/*' />
|
||||
public bool Contains (object config)
|
||||
{
|
||||
return configList.Contains (config);
|
||||
}
|
||||
|
||||
/// <include file='ConfigCollection.xml' path='//Method[@name="IndexOf"]/docs/*' />
|
||||
public int IndexOf (object config)
|
||||
{
|
||||
return configList.IndexOf (config);
|
||||
}
|
||||
|
||||
/// <include file='ConfigCollection.xml' path='//Method[@name="Insert"]/docs/*' />
|
||||
public void Insert (int index, object config)
|
||||
{
|
||||
configList.Insert (index, config);
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region Public events
|
||||
/// <include file='ConfigCollection.xml' path='//Event[@name="ConfigAdded"]/docs/*' />
|
||||
public event ConfigEventHandler ConfigAdded;
|
||||
|
||||
/// <include file='ConfigCollection.xml' path='//Event[@name="ConfigRemoved"]/docs/*' />
|
||||
public event ConfigEventHandler ConfigRemoved;
|
||||
#endregion
|
||||
|
||||
#region Protected methods
|
||||
/// <include file='ConfigCollection.xml' path='//Method[@name="OnConfigAdded"]/docs/*' />
|
||||
protected void OnConfigAdded (ConfigEventArgs e)
|
||||
{
|
||||
if (ConfigAdded != null) {
|
||||
ConfigAdded (this, e);
|
||||
}
|
||||
}
|
||||
|
||||
/// <include file='ConfigCollection.xml' path='//Method[@name="OnConfigRemoved"]/docs/*' />
|
||||
protected void OnConfigRemoved (ConfigEventArgs e)
|
||||
{
|
||||
if (ConfigRemoved != null) {
|
||||
ConfigRemoved (this, e);
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region Private methods
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
219
ExtensionLoader/Nini/Config/ConfigSourceBase.cs
Normal file
219
ExtensionLoader/Nini/Config/ConfigSourceBase.cs
Normal file
@@ -0,0 +1,219 @@
|
||||
#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.Text;
|
||||
using System.Collections;
|
||||
|
||||
namespace Nini.Config
|
||||
{
|
||||
/// <include file='IConfigSource.xml' path='//Interface[@name="IConfigSource"]/docs/*' />
|
||||
public abstract class ConfigSourceBase : IConfigSource
|
||||
{
|
||||
#region Private variables
|
||||
ArrayList sourceList = new ArrayList ();
|
||||
ConfigCollection configList = null;
|
||||
bool autoSave = false;
|
||||
AliasText alias = new AliasText ();
|
||||
#endregion
|
||||
|
||||
#region Constructors
|
||||
/// <include file='ConfigSourceBase.xml' path='//Constructor[@name="Constructor"]/docs/*' />
|
||||
public ConfigSourceBase ()
|
||||
{
|
||||
configList = new ConfigCollection (this);
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region Public properties
|
||||
/// <include file='IConfigSource.xml' path='//Property[@name="Configs"]/docs/*' />
|
||||
public ConfigCollection Configs
|
||||
{
|
||||
get { return configList; }
|
||||
}
|
||||
|
||||
/// <include file='IConfigSource.xml' path='//Property[@name="AutoSave"]/docs/*' />
|
||||
public bool AutoSave
|
||||
{
|
||||
get { return autoSave; }
|
||||
set { autoSave = value; }
|
||||
}
|
||||
|
||||
/// <include file='IConfigSource.xml' path='//Property[@name="Alias"]/docs/*' />
|
||||
public AliasText Alias
|
||||
{
|
||||
get { return alias; }
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region Public methods
|
||||
/// <include file='IConfigSource.xml' path='//Method[@name="Merge"]/docs/*' />
|
||||
public void Merge (IConfigSource source)
|
||||
{
|
||||
if (!sourceList.Contains (source)) {
|
||||
sourceList.Add (source);
|
||||
}
|
||||
|
||||
foreach (IConfig config in source.Configs)
|
||||
{
|
||||
this.Configs.Add (config);
|
||||
}
|
||||
}
|
||||
|
||||
/// <include file='IConfigSource.xml' path='//Method[@name="AddConfig"]/docs/*' />
|
||||
public virtual IConfig AddConfig (string name)
|
||||
{
|
||||
return configList.Add (name);
|
||||
}
|
||||
|
||||
/// <include file='IConfigSource.xml' path='//Method[@name="GetExpanded"]/docs/*' />
|
||||
public string GetExpanded (IConfig config, string key)
|
||||
{
|
||||
return Expand (config, key, false);
|
||||
}
|
||||
|
||||
/// <include file='IConfigSource.xml' path='//Method[@name="Save"]/docs/*' />
|
||||
public virtual void Save ()
|
||||
{
|
||||
OnSaved (new EventArgs ());
|
||||
}
|
||||
|
||||
/// <include file='IConfigSource.xml' path='//Method[@name="Reload"]/docs/*' />
|
||||
public virtual void Reload ()
|
||||
{
|
||||
OnReloaded (new EventArgs ());
|
||||
}
|
||||
|
||||
/// <include file='IConfigSource.xml' path='//Method[@name="ExpandKeyValues"]/docs/*' />
|
||||
public void ExpandKeyValues ()
|
||||
{
|
||||
string[] keys = null;
|
||||
|
||||
foreach (IConfig config in configList)
|
||||
{
|
||||
keys = config.GetKeys ();
|
||||
for (int i = 0; i < keys.Length; i++)
|
||||
{
|
||||
Expand (config, keys[i], true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <include file='IConfigSource.xml' path='//Method[@name="ReplaceKeyValues"]/docs/*' />
|
||||
public void ReplaceKeyValues ()
|
||||
{
|
||||
ExpandKeyValues ();
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region Public events
|
||||
/// <include file='IConfigSource.xml' path='//Event[@name="Reloaded"]/docs/*' />
|
||||
public event EventHandler Reloaded;
|
||||
|
||||
/// <include file='IConfigSource.xml' path='//Event[@name="Saved"]/docs/*' />
|
||||
public event EventHandler Saved;
|
||||
#endregion
|
||||
|
||||
#region Protected methods
|
||||
/// <include file='ConfigSourceBase.xml' path='//Method[@name="OnReloaded"]/docs/*' />
|
||||
protected void OnReloaded (EventArgs e)
|
||||
{
|
||||
if (Reloaded != null) {
|
||||
Reloaded (this, e);
|
||||
}
|
||||
}
|
||||
|
||||
/// <include file='ConfigSourceBase.xml' path='//Method[@name="OnSaved"]/docs/*' />
|
||||
protected void OnSaved (EventArgs e)
|
||||
{
|
||||
if (Saved != null) {
|
||||
Saved (this, e);
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region Private methods
|
||||
/// <summary>
|
||||
/// Expands key values from the given IConfig.
|
||||
/// </summary>
|
||||
private string Expand (IConfig config, string key, bool setValue)
|
||||
{
|
||||
string result = config.Get (key);
|
||||
if (result == null) {
|
||||
throw new ArgumentException (String.Format ("[{0}] not found in [{1}]",
|
||||
key, config.Name));
|
||||
}
|
||||
|
||||
while (true)
|
||||
{
|
||||
int startIndex = result.IndexOf ("${", 0);
|
||||
if (startIndex == -1) {
|
||||
break;
|
||||
}
|
||||
|
||||
int endIndex = result.IndexOf ("}", startIndex + 2);
|
||||
if (endIndex == -1) {
|
||||
break;
|
||||
}
|
||||
|
||||
string search = result.Substring (startIndex + 2,
|
||||
endIndex - (startIndex + 2));
|
||||
|
||||
if (search == key) {
|
||||
// Prevent infinite recursion
|
||||
throw new ArgumentException
|
||||
("Key cannot have a expand value of itself: " + key);
|
||||
}
|
||||
|
||||
string replace = ExpandValue (config, search);
|
||||
|
||||
result = result.Replace("${" + search + "}", replace);
|
||||
}
|
||||
|
||||
if (setValue) {
|
||||
config.Set(key, result);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns the replacement value of a config.
|
||||
/// </summary>
|
||||
private string ExpandValue (IConfig config, string search)
|
||||
{
|
||||
string result = null;
|
||||
|
||||
string[] replaces = search.Split ('|');
|
||||
|
||||
if (replaces.Length > 1) {
|
||||
IConfig newConfig = this.Configs[replaces[0]];
|
||||
if (newConfig == null) {
|
||||
throw new ArgumentException ("Expand config not found: "
|
||||
+ replaces[0]);
|
||||
}
|
||||
result = newConfig.Get (replaces[1]);
|
||||
if (result == null) {
|
||||
throw new ArgumentException ("Expand key not found: "
|
||||
+ replaces[1]);
|
||||
}
|
||||
} else {
|
||||
result = config.Get (search);
|
||||
|
||||
if (result == null) {
|
||||
throw new ArgumentException ("Key not found: " + search);
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
99
ExtensionLoader/Nini/Config/IConfig.cs
Normal file
99
ExtensionLoader/Nini/Config/IConfig.cs
Normal file
@@ -0,0 +1,99 @@
|
||||
#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;
|
||||
|
||||
namespace Nini.Config
|
||||
{
|
||||
/// <include file='IConfig.xml' path='//Interface[@name="IConfig"]/docs/*' />
|
||||
public interface IConfig
|
||||
{
|
||||
/// <include file='IConfig.xml' path='//Property[@name="ConfigSource"]/docs/*' />
|
||||
IConfigSource ConfigSource { get; }
|
||||
|
||||
/// <include file='IConfig.xml' path='//Property[@name="Name"]/docs/*' />
|
||||
string Name { get; set; }
|
||||
|
||||
/// <include file='IConfig.xml' path='//Property[@name="Alias"]/docs/*' />
|
||||
AliasText Alias { get; }
|
||||
|
||||
/// <include file='IConfig.xml' path='//Method[@name="Contains"]/docs/*' />
|
||||
bool Contains (string key);
|
||||
|
||||
/// <include file='IConfig.xml' path='//Method[@name="Get"]/docs/*' />
|
||||
string Get (string key);
|
||||
|
||||
/// <include file='IConfig.xml' path='//Method[@name="GetDefault"]/docs/*' />
|
||||
string Get (string key, string defaultValue);
|
||||
|
||||
/// <include file='IConfig.xml' path='//Method[@name="GetExpanded"]/docs/*' />
|
||||
string GetExpanded (string key);
|
||||
|
||||
/// <include file='IConfig.xml' path='//Method[@name="Get"]/docs/*' />
|
||||
string GetString (string key);
|
||||
|
||||
/// <include file='IConfig.xml' path='//Method[@name="GetDefault"]/docs/*' />
|
||||
string GetString (string key, string defaultValue);
|
||||
|
||||
/// <include file='IConfig.xml' path='//Method[@name="GetInt"]/docs/*' />
|
||||
int GetInt (string key);
|
||||
|
||||
/// <include file='IConfig.xml' path='//Method[@name="GetIntAlias"]/docs/*' />
|
||||
int GetInt (string key, bool fromAlias);
|
||||
|
||||
/// <include file='IConfig.xml' path='//Method[@name="GetIntDefault"]/docs/*' />
|
||||
int GetInt (string key, int defaultValue);
|
||||
|
||||
/// <include file='IConfig.xml' path='//Method[@name="GetIntDefaultAlias"]/docs/*' />
|
||||
int GetInt (string key, int defaultValue, bool fromAlias);
|
||||
|
||||
/// <include file='IConfig.xml' path='//Method[@name="GetLong"]/docs/*' />
|
||||
long GetLong (string key);
|
||||
|
||||
/// <include file='IConfig.xml' path='//Method[@name="GetLongDefault"]/docs/*' />
|
||||
long GetLong (string key, long defaultValue);
|
||||
|
||||
/// <include file='IConfig.xml' path='//Method[@name="GetBoolean"]/docs/*' />
|
||||
bool GetBoolean (string key);
|
||||
|
||||
/// <include file='IConfig.xml' path='//Method[@name="GetBooleanDefault"]/docs/*' />
|
||||
bool GetBoolean (string key, bool defaultValue);
|
||||
|
||||
/// <include file='IConfig.xml' path='//Method[@name="GetFloat"]/docs/*' />
|
||||
float GetFloat (string key);
|
||||
|
||||
/// <include file='IConfig.xml' path='//Method[@name="GetFloatDefault"]/docs/*' />
|
||||
float GetFloat (string key, float defaultValue);
|
||||
|
||||
/// <include file='IConfig.xml' path='//Method[@name="GetDouble"]/docs/*' />
|
||||
double GetDouble (string key);
|
||||
|
||||
/// <include file='IConfig.xml' path='//Method[@name="GetDoubleDefault"]/docs/*' />
|
||||
double GetDouble (string key, double defaultValue);
|
||||
|
||||
/// <include file='IConfig.xml' path='//Method[@name="GetKeys"]/docs/*' />
|
||||
string[] GetKeys ();
|
||||
|
||||
/// <include file='IConfig.xml' path='//Method[@name="GetValues"]/docs/*' />
|
||||
string[] GetValues ();
|
||||
|
||||
/// <include file='IConfig.xml' path='//Method[@name="Set"]/docs/*' />
|
||||
void Set (string key, object value);
|
||||
|
||||
/// <include file='IConfig.xml' path='//Method[@name="Remove"]/docs/*' />
|
||||
void Remove (string key);
|
||||
|
||||
/// <include file='IConfig.xml' path='//Event[@name="KeySet"]/docs/*' />
|
||||
event ConfigKeyEventHandler KeySet;
|
||||
|
||||
/// <include file='IConfig.xml' path='//Event[@name="KeyRemoved"]/docs/*' />
|
||||
event ConfigKeyEventHandler KeyRemoved;
|
||||
}
|
||||
}
|
||||
55
ExtensionLoader/Nini/Config/IConfigSource.cs
Normal file
55
ExtensionLoader/Nini/Config/IConfigSource.cs
Normal file
@@ -0,0 +1,55 @@
|
||||
#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;
|
||||
|
||||
namespace Nini.Config
|
||||
{
|
||||
/// <include file='IConfigSource.xml' path='//Interface[@name="IConfigSource"]/docs/*' />
|
||||
public interface IConfigSource
|
||||
{
|
||||
/// <include file='IConfigSource.xml' path='//Property[@name="Configs"]/docs/*' />
|
||||
ConfigCollection Configs { get; }
|
||||
|
||||
/// <include file='IConfigSource.xml' path='//Property[@name="AutoSave"]/docs/*' />
|
||||
bool AutoSave { get; set; }
|
||||
|
||||
/// <include file='IConfigSource.xml' path='//Property[@name="Alias"]/docs/*' />
|
||||
AliasText Alias { get; }
|
||||
|
||||
/// <include file='IConfigSource.xml' path='//Method[@name="Merge"]/docs/*' />
|
||||
void Merge (IConfigSource source);
|
||||
|
||||
/// <include file='IConfigSource.xml' path='//Method[@name="Save"]/docs/*' />
|
||||
void Save ();
|
||||
|
||||
/// <include file='IConfigSource.xml' path='//Method[@name="Reload"]/docs/*' />
|
||||
void Reload ();
|
||||
|
||||
/// <include file='IConfigSource.xml' path='//Method[@name="AddConfig"]/docs/*' />
|
||||
IConfig AddConfig (string name);
|
||||
|
||||
/// <include file='IConfigSource.xml' path='//Method[@name="GetExpanded"]/docs/*' />
|
||||
string GetExpanded (IConfig config, string key);
|
||||
|
||||
/// <include file='IConfigSource.xml' path='//Method[@name="ExpandKeyValues"]/docs/*' />
|
||||
void ExpandKeyValues ();
|
||||
|
||||
/// <include file='IConfigSource.xml' path='//Method[@name="ReplaceKeyValues"]/docs/*' />
|
||||
void ReplaceKeyValues ();
|
||||
|
||||
/// <include file='IConfigSource.xml' path='//Event[@name="Reloaded"]/docs/*' />
|
||||
event EventHandler Reloaded;
|
||||
|
||||
/// <include file='IConfigSource.xml' path='//Event[@name="Saved"]/docs/*' />
|
||||
event EventHandler Saved;
|
||||
}
|
||||
}
|
||||
90
ExtensionLoader/Nini/Config/IniConfig.cs
Normal file
90
ExtensionLoader/Nini/Config/IniConfig.cs
Normal file
@@ -0,0 +1,90 @@
|
||||
#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.Collections;
|
||||
using System.Globalization;
|
||||
using Nini.Util;
|
||||
|
||||
namespace Nini.Config
|
||||
{
|
||||
/// <include file='IniConfig.xml' path='//Class[@name="IniConfig"]/docs/*' />
|
||||
public class IniConfig : ConfigBase
|
||||
{
|
||||
#region Private variables
|
||||
IniConfigSource parent = null;
|
||||
#endregion
|
||||
|
||||
#region Constructors
|
||||
/// <include file='IniConfig.xml' path='//Constructor[@name="Constructor"]/docs/*' />
|
||||
public IniConfig (string name, IConfigSource source)
|
||||
: base(name, source)
|
||||
{
|
||||
parent = (IniConfigSource)source;
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region Public properties
|
||||
#endregion
|
||||
|
||||
#region Public methods
|
||||
/// <include file='IniConfig.xml' path='//Method[@name="Get"]/docs/*' />
|
||||
public override string Get (string key)
|
||||
{
|
||||
if (!parent.CaseSensitive) {
|
||||
key = CaseInsensitiveKeyName (key);
|
||||
}
|
||||
|
||||
return base.Get (key);
|
||||
}
|
||||
|
||||
/// <include file='IniConfig.xml' path='//Method[@name="Set"]/docs/*' />
|
||||
public override void Set (string key, object value)
|
||||
{
|
||||
if (!parent.CaseSensitive) {
|
||||
key = CaseInsensitiveKeyName (key);
|
||||
}
|
||||
|
||||
base.Set (key, value);
|
||||
}
|
||||
|
||||
/// <include file='IniConfig.xml' path='//Method[@name="Remove"]/docs/*' />
|
||||
public override void Remove (string key)
|
||||
{
|
||||
if (!parent.CaseSensitive) {
|
||||
key = CaseInsensitiveKeyName (key);
|
||||
}
|
||||
|
||||
base.Remove (key);
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region Private methods
|
||||
/// <summary>
|
||||
/// Returns the key name if the case insensitivity is turned on.
|
||||
/// </summary>
|
||||
private string CaseInsensitiveKeyName (string key)
|
||||
{
|
||||
string result = null;
|
||||
|
||||
string lowerKey = key.ToLower ();
|
||||
foreach (string currentKey in keys.Keys)
|
||||
{
|
||||
if (currentKey.ToLower () == lowerKey) {
|
||||
result = currentKey;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return (result == null) ? key : result;
|
||||
}
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
329
ExtensionLoader/Nini/Config/IniConfigSource.cs
Normal file
329
ExtensionLoader/Nini/Config/IniConfigSource.cs
Normal file
@@ -0,0 +1,329 @@
|
||||
#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 Nini.Ini;
|
||||
|
||||
namespace Nini.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
|
||||
}
|
||||
}
|
||||
302
ExtensionLoader/Nini/Ini/IniDocument.cs
Normal file
302
ExtensionLoader/Nini/Ini/IniDocument.cs
Normal file
@@ -0,0 +1,302 @@
|
||||
#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 Nini.Util;
|
||||
|
||||
namespace Nini.Ini
|
||||
{
|
||||
#region IniFileType enumeration
|
||||
/// <include file='IniDocument.xml' path='//Enum[@name="IniFileType"]/docs/*' />
|
||||
public enum IniFileType
|
||||
{
|
||||
/// <include file='IniDocument.xml' path='//Enum[@name="IniFileType"]/Value[@name="Standard"]/docs/*' />
|
||||
Standard,
|
||||
/// <include file='IniDocument.xml' path='//Enum[@name="IniFileType"]/Value[@name="PythonStyle"]/docs/*' />
|
||||
PythonStyle,
|
||||
/// <include file='IniDocument.xml' path='//Enum[@name="IniFileType"]/Value[@name="SambaStyle"]/docs/*' />
|
||||
SambaStyle,
|
||||
/// <include file='IniDocument.xml' path='//Enum[@name="IniFileType"]/Value[@name="MysqlStyle"]/docs/*' />
|
||||
MysqlStyle,
|
||||
/// <include file='IniDocument.xml' path='//Enum[@name="IniFileType"]/Value[@name="WindowsStyle"]/docs/*' />
|
||||
WindowsStyle
|
||||
}
|
||||
#endregion
|
||||
|
||||
/// <include file='IniDocument.xml' path='//Class[@name="IniDocument"]/docs/*' />
|
||||
public class IniDocument
|
||||
{
|
||||
#region Private variables
|
||||
IniSectionCollection sections = new IniSectionCollection ();
|
||||
ArrayList initialComment = new ArrayList ();
|
||||
IniFileType fileType = IniFileType.Standard;
|
||||
#endregion
|
||||
|
||||
#region Public properties
|
||||
/// <include file='IniDocument.xml' path='//Property[@name="FileType"]/docs/*' />
|
||||
public IniFileType FileType
|
||||
{
|
||||
get { return fileType; }
|
||||
set { fileType = value; }
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region Constructors
|
||||
/// <include file='IniDocument.xml' path='//Constructor[@name="ConstructorPath"]/docs/*' />
|
||||
public IniDocument (string filePath)
|
||||
{
|
||||
fileType = IniFileType.Standard;
|
||||
Load (filePath);
|
||||
}
|
||||
|
||||
/// <include file='IniDocument.xml' path='//Constructor[@name="ConstructorPathType"]/docs/*' />
|
||||
public IniDocument (string filePath, IniFileType type)
|
||||
{
|
||||
fileType = type;
|
||||
Load (filePath);
|
||||
}
|
||||
|
||||
/// <include file='IniDocument.xml' path='//Constructor[@name="ConstructorTextReader"]/docs/*' />
|
||||
public IniDocument (TextReader reader)
|
||||
{
|
||||
fileType = IniFileType.Standard;
|
||||
Load (reader);
|
||||
}
|
||||
|
||||
/// <include file='IniDocument.xml' path='//Constructor[@name="ConstructorTextReaderType"]/docs/*' />
|
||||
public IniDocument (TextReader reader, IniFileType type)
|
||||
{
|
||||
fileType = type;
|
||||
Load (reader);
|
||||
}
|
||||
|
||||
/// <include file='IniDocument.xml' path='//Constructor[@name="ConstructorStream"]/docs/*' />
|
||||
public IniDocument (Stream stream)
|
||||
{
|
||||
fileType = IniFileType.Standard;
|
||||
Load (stream);
|
||||
}
|
||||
|
||||
/// <include file='IniDocument.xml' path='//Constructor[@name="ConstructorStreamType"]/docs/*' />
|
||||
public IniDocument (Stream stream, IniFileType type)
|
||||
{
|
||||
fileType = type;
|
||||
Load (stream);
|
||||
}
|
||||
|
||||
/// <include file='IniDocument.xml' path='//Constructor[@name="ConstructorIniReader"]/docs/*' />
|
||||
public IniDocument (IniReader reader)
|
||||
{
|
||||
fileType = IniFileType.Standard;
|
||||
Load (reader);
|
||||
}
|
||||
|
||||
/// <include file='IniDocument.xml' path='//Constructor[@name="Constructor"]/docs/*' />
|
||||
public IniDocument ()
|
||||
{
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region Public methods
|
||||
/// <include file='IniDocument.xml' path='//Method[@name="LoadPath"]/docs/*' />
|
||||
public void Load (string filePath)
|
||||
{
|
||||
Load (new StreamReader (filePath));
|
||||
}
|
||||
|
||||
/// <include file='IniDocument.xml' path='//Method[@name="LoadTextReader"]/docs/*' />
|
||||
public void Load (TextReader reader)
|
||||
{
|
||||
Load (GetIniReader (reader, fileType));
|
||||
}
|
||||
|
||||
/// <include file='IniDocument.xml' path='//Method[@name="LoadStream"]/docs/*' />
|
||||
public void Load (Stream stream)
|
||||
{
|
||||
Load (new StreamReader (stream));
|
||||
}
|
||||
|
||||
/// <include file='IniDocument.xml' path='//Method[@name="LoadIniReader"]/docs/*' />
|
||||
public void Load (IniReader reader)
|
||||
{
|
||||
LoadReader (reader);
|
||||
}
|
||||
|
||||
/// <include file='IniSection.xml' path='//Property[@name="Comment"]/docs/*' />
|
||||
public IniSectionCollection Sections
|
||||
{
|
||||
get { return sections; }
|
||||
}
|
||||
|
||||
/// <include file='IniDocument.xml' path='//Method[@name="SaveTextWriter"]/docs/*' />
|
||||
public void Save (TextWriter textWriter)
|
||||
{
|
||||
IniWriter writer = GetIniWriter (textWriter, fileType);
|
||||
IniItem item = null;
|
||||
IniSection section = null;
|
||||
|
||||
foreach (string comment in initialComment)
|
||||
{
|
||||
writer.WriteEmpty (comment);
|
||||
}
|
||||
|
||||
for (int j = 0; j < sections.Count; j++)
|
||||
{
|
||||
section = sections[j];
|
||||
writer.WriteSection (section.Name, section.Comment);
|
||||
for (int i = 0; i < section.ItemCount; i++)
|
||||
{
|
||||
item = section.GetItem (i);
|
||||
switch (item.Type)
|
||||
{
|
||||
case IniType.Key:
|
||||
writer.WriteKey (item.Name, item.Value, item.Comment);
|
||||
break;
|
||||
case IniType.Empty:
|
||||
writer.WriteEmpty (item.Comment);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
writer.Close ();
|
||||
}
|
||||
|
||||
/// <include file='IniDocument.xml' path='//Method[@name="SavePath"]/docs/*' />
|
||||
public void Save (string filePath)
|
||||
{
|
||||
StreamWriter writer = new StreamWriter (filePath);
|
||||
Save (writer);
|
||||
writer.Close ();
|
||||
}
|
||||
|
||||
/// <include file='IniDocument.xml' path='//Method[@name="SaveStream"]/docs/*' />
|
||||
public void Save (Stream stream)
|
||||
{
|
||||
Save (new StreamWriter (stream));
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region Private methods
|
||||
/// <summary>
|
||||
/// Loads the file not saving comments.
|
||||
/// </summary>
|
||||
private void LoadReader (IniReader reader)
|
||||
{
|
||||
reader.IgnoreComments = false;
|
||||
bool sectionFound = false;
|
||||
IniSection section = null;
|
||||
|
||||
try {
|
||||
while (reader.Read ())
|
||||
{
|
||||
switch (reader.Type)
|
||||
{
|
||||
case IniType.Empty:
|
||||
if (!sectionFound) {
|
||||
initialComment.Add (reader.Comment);
|
||||
} else {
|
||||
section.Set (reader.Comment);
|
||||
}
|
||||
|
||||
break;
|
||||
case IniType.Section:
|
||||
sectionFound = true;
|
||||
// If section already exists then overwrite it
|
||||
if (sections[reader.Name] != null) {
|
||||
sections.Remove (reader.Name);
|
||||
}
|
||||
section = new IniSection (reader.Name, reader.Comment);
|
||||
sections.Add (section);
|
||||
|
||||
break;
|
||||
case IniType.Key:
|
||||
if (section.GetValue (reader.Name) == null) {
|
||||
section.Set (reader.Name, reader.Value, reader.Comment);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
} catch (Exception ex) {
|
||||
throw ex;
|
||||
} finally {
|
||||
// Always close the file
|
||||
reader.Close ();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns a proper INI reader depending upon the type parameter.
|
||||
/// </summary>
|
||||
private IniReader GetIniReader (TextReader reader, IniFileType type)
|
||||
{
|
||||
IniReader result = new IniReader (reader);
|
||||
|
||||
switch (type)
|
||||
{
|
||||
case IniFileType.Standard:
|
||||
// do nothing
|
||||
break;
|
||||
case IniFileType.PythonStyle:
|
||||
result.AcceptCommentAfterKey = false;
|
||||
result.SetCommentDelimiters (new char[] { ';', '#' });
|
||||
result.SetAssignDelimiters (new char[] { ':' });
|
||||
break;
|
||||
case IniFileType.SambaStyle:
|
||||
result.AcceptCommentAfterKey = false;
|
||||
result.SetCommentDelimiters (new char[] { ';', '#' });
|
||||
result.LineContinuation = true;
|
||||
break;
|
||||
case IniFileType.MysqlStyle:
|
||||
result.AcceptCommentAfterKey = false;
|
||||
result.AcceptNoAssignmentOperator = true;
|
||||
result.SetCommentDelimiters (new char[] { '#' });
|
||||
result.SetAssignDelimiters (new char[] { ':', '=' });
|
||||
break;
|
||||
case IniFileType.WindowsStyle:
|
||||
result.ConsumeAllKeyText = true;
|
||||
break;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns a proper IniWriter depending upon the type parameter.
|
||||
/// </summary>
|
||||
private IniWriter GetIniWriter (TextWriter reader, IniFileType type)
|
||||
{
|
||||
IniWriter result = new IniWriter (reader);
|
||||
|
||||
switch (type)
|
||||
{
|
||||
case IniFileType.Standard:
|
||||
case IniFileType.WindowsStyle:
|
||||
// do nothing
|
||||
break;
|
||||
case IniFileType.PythonStyle:
|
||||
result.AssignDelimiter = ':';
|
||||
result.CommentDelimiter = '#';
|
||||
break;
|
||||
case IniFileType.SambaStyle:
|
||||
case IniFileType.MysqlStyle:
|
||||
result.AssignDelimiter = '=';
|
||||
result.CommentDelimiter = '#';
|
||||
break;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
|
||||
121
ExtensionLoader/Nini/Ini/IniException.cs
Normal file
121
ExtensionLoader/Nini/Ini/IniException.cs
Normal file
@@ -0,0 +1,121 @@
|
||||
#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.Security;
|
||||
using System.Globalization;
|
||||
using System.Security.Permissions;
|
||||
using System.Runtime.Serialization;
|
||||
using System.Runtime.Serialization.Formatters.Binary;
|
||||
|
||||
|
||||
namespace Nini.Ini
|
||||
{
|
||||
/// <include file='IniException.xml' path='//Class[@name="IniException"]/docs/*' />
|
||||
#if (NET_COMPACT_1_0)
|
||||
#else
|
||||
[Serializable]
|
||||
#endif
|
||||
public class IniException : SystemException /*, ISerializable */
|
||||
{
|
||||
#region Private variables
|
||||
IniReader iniReader = null;
|
||||
string message = "";
|
||||
#endregion
|
||||
|
||||
#region Public properties
|
||||
/// <include file='IniException.xml' path='//Property[@name="LinePosition"]/docs/*' />
|
||||
public int LinePosition
|
||||
{
|
||||
get {
|
||||
return (iniReader == null) ? 0 : iniReader.LinePosition;
|
||||
}
|
||||
}
|
||||
|
||||
/// <include file='IniException.xml' path='//Property[@name="LineNumber"]/docs/*' />
|
||||
public int LineNumber
|
||||
{
|
||||
get {
|
||||
return (iniReader == null) ? 0 : iniReader.LineNumber;
|
||||
}
|
||||
}
|
||||
|
||||
/// <include file='IniException.xml' path='//Property[@name="Message"]/docs/*' />
|
||||
public override string Message
|
||||
{
|
||||
get {
|
||||
if (iniReader == null) {
|
||||
return base.Message;
|
||||
}
|
||||
|
||||
return String.Format (CultureInfo.InvariantCulture, "{0} - Line: {1}, Position: {2}.",
|
||||
message, this.LineNumber, this.LinePosition);
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region Constructors
|
||||
/// <include file='IniException.xml' path='//Constructor[@name="Constructor"]/docs/*' />
|
||||
public IniException ()
|
||||
: base ()
|
||||
{
|
||||
this.message = "An error has occurred";
|
||||
}
|
||||
|
||||
/// <include file='IniException.xml' path='//Constructor[@name="ConstructorException"]/docs/*' />
|
||||
public IniException (string message, Exception exception)
|
||||
: base (message, exception)
|
||||
{
|
||||
}
|
||||
|
||||
/// <include file='IniException.xml' path='//Constructor[@name="ConstructorMessage"]/docs/*' />
|
||||
public IniException (string message)
|
||||
: base (message)
|
||||
{
|
||||
this.message = message;
|
||||
}
|
||||
|
||||
/// <include file='IniException.xml' path='//Constructor[@name="ConstructorTextReader"]/docs/*' />
|
||||
internal IniException (IniReader reader, string message)
|
||||
: this (message)
|
||||
{
|
||||
iniReader = reader;
|
||||
this.message = message;
|
||||
}
|
||||
|
||||
#if (NET_COMPACT_1_0)
|
||||
#else
|
||||
/// <include file='IniException.xml' path='//Constructor[@name="ConstructorSerialize"]/docs/*' />
|
||||
protected IniException (SerializationInfo info, StreamingContext context)
|
||||
: base (info, context)
|
||||
{
|
||||
}
|
||||
#endif
|
||||
#endregion
|
||||
|
||||
#region Public methods
|
||||
#if (NET_COMPACT_1_0)
|
||||
#else
|
||||
/// <include file='IniException.xml' path='//Method[@name="GetObjectData"]/docs/*' />
|
||||
[SecurityPermissionAttribute(SecurityAction.Demand,SerializationFormatter=true)]
|
||||
public override void GetObjectData (SerializationInfo info,
|
||||
StreamingContext context)
|
||||
{
|
||||
base.GetObjectData (info, context);
|
||||
if (iniReader != null) {
|
||||
info.AddValue ("lineNumber", iniReader.LineNumber);
|
||||
|
||||
info.AddValue ("linePosition", iniReader.LinePosition);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
54
ExtensionLoader/Nini/Ini/IniItem.cs
Normal file
54
ExtensionLoader/Nini/Ini/IniItem.cs
Normal file
@@ -0,0 +1,54 @@
|
||||
using System;
|
||||
|
||||
namespace Nini.Ini
|
||||
{
|
||||
/// <include file='IniItem.xml' path='//Class[@name="IniItem"]/docs/*' />
|
||||
public class IniItem
|
||||
{
|
||||
#region Private variables
|
||||
IniType iniType = IniType.Empty;
|
||||
string iniName = "";
|
||||
string iniValue = "";
|
||||
string iniComment = null;
|
||||
#endregion
|
||||
|
||||
#region Public properties
|
||||
/// <include file='IniItem.xml' path='//Property[@name="Type"]/docs/*' />
|
||||
public IniType Type
|
||||
{
|
||||
get { return iniType; }
|
||||
set { iniType = value; }
|
||||
}
|
||||
|
||||
/// <include file='IniItem.xml' path='//Property[@name="Value"]/docs/*' />
|
||||
public string Value
|
||||
{
|
||||
get { return iniValue; }
|
||||
set { iniValue = value; }
|
||||
}
|
||||
|
||||
/// <include file='IniItem.xml' path='//Property[@name="Name"]/docs/*' />
|
||||
public string Name
|
||||
{
|
||||
get { return iniName; }
|
||||
}
|
||||
|
||||
/// <include file='IniItem.xml' path='//Property[@name="Comment"]/docs/*' />
|
||||
public string Comment
|
||||
{
|
||||
get { return iniComment; }
|
||||
set { iniComment = value; }
|
||||
}
|
||||
#endregion
|
||||
|
||||
/// <include file='IniItem.xml' path='//Constructor[@name="Constructor"]/docs/*' />
|
||||
internal protected IniItem (string name, string value, IniType type, string comment)
|
||||
{
|
||||
iniName = name;
|
||||
iniValue = value;
|
||||
iniType = type;
|
||||
iniComment = comment;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
652
ExtensionLoader/Nini/Ini/IniReader.cs
Normal file
652
ExtensionLoader/Nini/Ini/IniReader.cs
Normal file
@@ -0,0 +1,652 @@
|
||||
#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.Text;
|
||||
using System.Collections;
|
||||
|
||||
namespace Nini.Ini
|
||||
{
|
||||
#region IniReadState enumeration
|
||||
/// <include file='IniReader.xml' path='//Enum[@name="IniReadState"]/docs/*' />
|
||||
public enum IniReadState : int
|
||||
{
|
||||
/// <include file='IniReader.xml' path='//Enum[@name="IniReadState"]/Value[@name="Closed"]/docs/*' />
|
||||
Closed,
|
||||
/// <include file='IniReader.xml' path='//Enum[@name="IniReadState"]/Value[@name="EndOfFile"]/docs/*' />
|
||||
EndOfFile,
|
||||
/// <include file='IniReader.xml' path='//Enum[@name="IniReadState"]/Value[@name="Error"]/docs/*' />
|
||||
Error,
|
||||
/// <include file='IniReader.xml' path='//Enum[@name="IniReadState"]/Value[@name="Initial"]/docs/*' />
|
||||
Initial,
|
||||
/// <include file='IniReader.xml' path='//Enum[@name="IniReadState"]/Value[@name="Interactive"]/docs/*' />
|
||||
Interactive
|
||||
};
|
||||
#endregion
|
||||
|
||||
#region IniType enumeration
|
||||
/// <include file='IniReader.xml' path='//Enum[@name="IniType"]/docs/*' />
|
||||
public enum IniType : int
|
||||
{
|
||||
/// <include file='IniReader.xml' path='//Enum[@name="IniType"]/Value[@name="Section"]/docs/*' />
|
||||
Section,
|
||||
/// <include file='IniReader.xml' path='//Enum[@name="IniType"]/Value[@name="Key"]/docs/*' />
|
||||
Key,
|
||||
/// <include file='IniReader.xml' path='//Enum[@name="IniType"]/Value[@name="Empty"]/docs/*' />
|
||||
Empty
|
||||
}
|
||||
#endregion
|
||||
|
||||
/// <include file='IniReader.xml' path='//Class[@name="IniReader"]/docs/*' />
|
||||
public class IniReader : IDisposable
|
||||
{
|
||||
#region Private variables
|
||||
int lineNumber = 1;
|
||||
int column = 1;
|
||||
IniType iniType = IniType.Empty;
|
||||
TextReader textReader = null;
|
||||
bool ignoreComments = false;
|
||||
StringBuilder name = new StringBuilder ();
|
||||
StringBuilder value = new StringBuilder ();
|
||||
StringBuilder comment = new StringBuilder ();
|
||||
IniReadState readState = IniReadState.Initial;
|
||||
bool hasComment = false;
|
||||
bool disposed = false;
|
||||
bool lineContinuation = false;
|
||||
bool acceptCommentAfterKey = true;
|
||||
bool acceptNoAssignmentOperator = false;
|
||||
bool consumeAllKeyText = false;
|
||||
char[] commentDelimiters = new char[] { ';' };
|
||||
char[] assignDelimiters = new char[] { '=' };
|
||||
#endregion
|
||||
|
||||
#region Public properties
|
||||
/// <include file='IniReader.xml' path='//Property[@name="Name"]/docs/*' />
|
||||
public string Name
|
||||
{
|
||||
get { return this.name.ToString (); }
|
||||
}
|
||||
|
||||
/// <include file='IniReader.xml' path='//Property[@name="Value"]/docs/*' />
|
||||
public string Value
|
||||
{
|
||||
get { return this.value.ToString (); }
|
||||
}
|
||||
|
||||
/// <include file='IniReader.xml' path='//Property[@name="Type"]/docs/*' />
|
||||
public IniType Type
|
||||
{
|
||||
get { return iniType; }
|
||||
}
|
||||
|
||||
/// <include file='IniReader.xml' path='//Property[@name="Comment"]/docs/*' />
|
||||
public string Comment
|
||||
{
|
||||
get { return (hasComment) ? this.comment.ToString () : null; }
|
||||
}
|
||||
|
||||
/// <include file='IniReader.xml' path='//Property[@name="LineNumber"]/docs/*' />
|
||||
public int LineNumber
|
||||
{
|
||||
get { return lineNumber; }
|
||||
}
|
||||
|
||||
/// <include file='IniReader.xml' path='//Property[@name="LinePosition"]/docs/*' />
|
||||
public int LinePosition
|
||||
{
|
||||
get { return column; }
|
||||
}
|
||||
|
||||
/// <include file='IniReader.xml' path='//Property[@name="IgnoreComments"]/docs/*' />
|
||||
public bool IgnoreComments
|
||||
{
|
||||
get { return ignoreComments; }
|
||||
set { ignoreComments = value; }
|
||||
}
|
||||
|
||||
/// <include file='IniReader.xml' path='//Property[@name="ReadState"]/docs/*' />
|
||||
public IniReadState ReadState
|
||||
{
|
||||
get { return readState; }
|
||||
}
|
||||
|
||||
/// <include file='IniReader.xml' path='//Property[@name="LineContinuation"]/docs/*' />
|
||||
public bool LineContinuation
|
||||
{
|
||||
get { return lineContinuation; }
|
||||
set { lineContinuation = value; }
|
||||
}
|
||||
|
||||
/// <include file='IniReader.xml' path='//Property[@name="AcceptCommentAfterKey"]/docs/*' />
|
||||
public bool AcceptCommentAfterKey
|
||||
{
|
||||
get { return acceptCommentAfterKey; }
|
||||
set { acceptCommentAfterKey = value; }
|
||||
}
|
||||
|
||||
/// <include file='IniReader.xml' path='//Property[@name="AcceptNoAssignmentOperator"]/docs/*' />
|
||||
public bool AcceptNoAssignmentOperator
|
||||
{
|
||||
get { return acceptNoAssignmentOperator; }
|
||||
set { acceptNoAssignmentOperator = value; }
|
||||
}
|
||||
|
||||
/// <include file='IniReader.xml' path='//Property[@name="ConsumeAllKeyText"]/docs/*' />
|
||||
public bool ConsumeAllKeyText
|
||||
{
|
||||
get { return consumeAllKeyText; }
|
||||
set { consumeAllKeyText = value; }
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region Constructors
|
||||
/// <include file='IniReader.xml' path='//Constructor[@name="ConstructorPath"]/docs/*' />
|
||||
public IniReader (string filePath)
|
||||
{
|
||||
textReader = new StreamReader (filePath);
|
||||
}
|
||||
|
||||
/// <include file='IniReader.xml' path='//Constructor[@name="ConstructorTextReader"]/docs/*' />
|
||||
public IniReader (TextReader reader)
|
||||
{
|
||||
textReader = reader;
|
||||
}
|
||||
|
||||
/// <include file='IniReader.xml' path='//Constructor[@name="ConstructorStream"]/docs/*' />
|
||||
public IniReader (Stream stream)
|
||||
: this (new StreamReader (stream))
|
||||
{
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region Public methods
|
||||
/// <include file='IniReader.xml' path='//Method[@name="Read"]/docs/*' />
|
||||
public bool Read ()
|
||||
{
|
||||
bool result = false;
|
||||
|
||||
if (readState != IniReadState.EndOfFile
|
||||
|| readState != IniReadState.Closed) {
|
||||
readState = IniReadState.Interactive;
|
||||
result = ReadNext ();
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/// <include file='IniReader.xml' path='//Method[@name="MoveToNextSection"]/docs/*' />
|
||||
public bool MoveToNextSection ()
|
||||
{
|
||||
bool result = false;
|
||||
|
||||
while (true)
|
||||
{
|
||||
result = Read ();
|
||||
|
||||
if (iniType == IniType.Section || !result) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/// <include file='IniReader.xml' path='//Method[@name="MoveToNextKey"]/docs/*' />
|
||||
public bool MoveToNextKey ()
|
||||
{
|
||||
bool result = false;
|
||||
|
||||
while (true)
|
||||
{
|
||||
result = Read ();
|
||||
|
||||
if (iniType == IniType.Section) {
|
||||
result = false;
|
||||
break;
|
||||
}
|
||||
if (iniType == IniType.Key || !result) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/// <include file='IniReader.xml' path='//Method[@name="Close"]/docs/*' />
|
||||
public void Close ()
|
||||
{
|
||||
Reset ();
|
||||
readState = IniReadState.Closed;
|
||||
|
||||
if (textReader != null) {
|
||||
textReader.Close ();
|
||||
}
|
||||
}
|
||||
|
||||
/// <include file='IniReader.xml' path='//Method[@name="Dispose"]/docs/*' />
|
||||
public void Dispose ()
|
||||
{
|
||||
Dispose (true);
|
||||
}
|
||||
|
||||
/// <include file='IniReader.xml' path='//Method[@name="GetCommentDelimiters"]/docs/*' />
|
||||
public char[] GetCommentDelimiters ()
|
||||
{
|
||||
char[] result = new char[commentDelimiters.Length];
|
||||
Array.Copy (commentDelimiters, 0, result, 0, commentDelimiters.Length);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/// <include file='IniReader.xml' path='//Method[@name="SetCommentDelimiters"]/docs/*' />
|
||||
public void SetCommentDelimiters (char[] delimiters)
|
||||
{
|
||||
if (delimiters.Length < 1) {
|
||||
throw new ArgumentException ("Must supply at least one delimiter");
|
||||
}
|
||||
|
||||
commentDelimiters = delimiters;
|
||||
}
|
||||
|
||||
/// <include file='IniReader.xml' path='//Method[@name="GetAssignDelimiters"]/docs/*' />
|
||||
public char[] GetAssignDelimiters ()
|
||||
{
|
||||
char[] result = new char[assignDelimiters.Length];
|
||||
Array.Copy (assignDelimiters, 0, result, 0, assignDelimiters.Length);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/// <include file='IniReader.xml' path='//Method[@name="SetAssignDelimiters"]/docs/*' />
|
||||
public void SetAssignDelimiters (char[] delimiters)
|
||||
{
|
||||
if (delimiters.Length < 1) {
|
||||
throw new ArgumentException ("Must supply at least one delimiter");
|
||||
}
|
||||
|
||||
assignDelimiters = delimiters;
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region Protected methods
|
||||
/// <include file='IniReader.xml' path='//Method[@name="DisposeBoolean"]/docs/*' />
|
||||
protected virtual void Dispose (bool disposing)
|
||||
{
|
||||
if (!disposed) {
|
||||
textReader.Close ();
|
||||
disposed = true;
|
||||
|
||||
if (disposing) {
|
||||
GC.SuppressFinalize (this);
|
||||
}
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region Private methods
|
||||
/// <summary>
|
||||
/// Destructor.
|
||||
/// </summary>
|
||||
~IniReader ()
|
||||
{
|
||||
Dispose (false);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Resets all of the current INI line data.
|
||||
/// </summary>
|
||||
private void Reset ()
|
||||
{
|
||||
this.name.Remove (0, this.name.Length);
|
||||
this.value.Remove (0, this.value.Length);
|
||||
this.comment.Remove (0, this.comment.Length);
|
||||
iniType = IniType.Empty;
|
||||
hasComment = false;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Reads the next INI line item.
|
||||
/// </summary>
|
||||
private bool ReadNext ()
|
||||
{
|
||||
bool result = true;
|
||||
int ch = PeekChar ();
|
||||
Reset ();
|
||||
|
||||
if (IsComment (ch)) {
|
||||
iniType = IniType.Empty;
|
||||
ReadChar (); // consume comment character
|
||||
ReadComment ();
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
switch (ch)
|
||||
{
|
||||
case ' ':
|
||||
case '\t':
|
||||
case '\r':
|
||||
SkipWhitespace ();
|
||||
ReadNext ();
|
||||
break;
|
||||
case '\n':
|
||||
ReadChar ();
|
||||
break;
|
||||
case '[':
|
||||
ReadSection ();
|
||||
break;
|
||||
case -1:
|
||||
readState = IniReadState.EndOfFile;
|
||||
result = false;
|
||||
break;
|
||||
default:
|
||||
ReadKey ();
|
||||
break;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Reads a comment. Must start after the comment delimiter.
|
||||
/// </summary>
|
||||
private void ReadComment ()
|
||||
{
|
||||
int ch = -1;
|
||||
SkipWhitespace ();
|
||||
hasComment = true;
|
||||
|
||||
do
|
||||
{
|
||||
ch = ReadChar ();
|
||||
this.comment.Append ((char)ch);
|
||||
} while (!EndOfLine (ch));
|
||||
|
||||
RemoveTrailingWhitespace (this.comment);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Removes trailing whitespace from a StringBuilder.
|
||||
/// </summary>
|
||||
private void RemoveTrailingWhitespace (StringBuilder builder)
|
||||
{
|
||||
string temp = builder.ToString ();
|
||||
|
||||
builder.Remove (0, builder.Length);
|
||||
builder.Append (temp.TrimEnd (null));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Reads a key.
|
||||
/// </summary>
|
||||
private void ReadKey ()
|
||||
{
|
||||
int ch = -1;
|
||||
iniType = IniType.Key;
|
||||
|
||||
while (true)
|
||||
{
|
||||
ch = PeekChar ();
|
||||
|
||||
if (IsAssign (ch)) {
|
||||
ReadChar ();
|
||||
break;
|
||||
}
|
||||
|
||||
if (EndOfLine (ch)) {
|
||||
if (acceptNoAssignmentOperator) {
|
||||
break;
|
||||
}
|
||||
throw new IniException (this,
|
||||
String.Format ("Expected assignment operator ({0})",
|
||||
assignDelimiters[0]));
|
||||
}
|
||||
|
||||
this.name.Append ((char)ReadChar ());
|
||||
}
|
||||
|
||||
ReadKeyValue ();
|
||||
SearchForComment ();
|
||||
RemoveTrailingWhitespace (this.name);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Reads the value of a key.
|
||||
/// </summary>
|
||||
private void ReadKeyValue ()
|
||||
{
|
||||
int ch = -1;
|
||||
bool foundQuote = false;
|
||||
int characters = 0;
|
||||
SkipWhitespace ();
|
||||
|
||||
while (true)
|
||||
{
|
||||
ch = PeekChar ();
|
||||
|
||||
if (!IsWhitespace (ch)) {
|
||||
characters++;
|
||||
}
|
||||
|
||||
if (!this.ConsumeAllKeyText && ch == '"') {
|
||||
ReadChar ();
|
||||
|
||||
if (!foundQuote && characters == 1) {
|
||||
foundQuote = true;
|
||||
continue;
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (foundQuote && EndOfLine (ch)) {
|
||||
throw new IniException (this, "Expected closing quote (\")");
|
||||
}
|
||||
|
||||
// Handle line continuation
|
||||
if (lineContinuation && ch == '\\')
|
||||
{
|
||||
StringBuilder buffer = new StringBuilder ();
|
||||
buffer.Append ((char)ReadChar ()); // append '\'
|
||||
|
||||
while (PeekChar () != '\n' && IsWhitespace (PeekChar ()))
|
||||
{
|
||||
if (PeekChar () != '\r') {
|
||||
buffer.Append ((char)ReadChar ());
|
||||
} else {
|
||||
ReadChar (); // consume '\r'
|
||||
}
|
||||
}
|
||||
|
||||
if (PeekChar () == '\n') {
|
||||
// continue reading key value on next line
|
||||
ReadChar ();
|
||||
continue;
|
||||
} else {
|
||||
// Replace consumed characters
|
||||
this.value.Append (buffer.ToString ());
|
||||
}
|
||||
}
|
||||
|
||||
if (!this.ConsumeAllKeyText) {
|
||||
// If accepting comments then don't consume as key value
|
||||
if (acceptCommentAfterKey && IsComment (ch) && !foundQuote) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Always break at end of line
|
||||
if (EndOfLine (ch)) {
|
||||
break;
|
||||
}
|
||||
|
||||
this.value.Append ((char)ReadChar ());
|
||||
}
|
||||
|
||||
if (!foundQuote) {
|
||||
RemoveTrailingWhitespace (this.value);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Reads an INI section.
|
||||
/// </summary>
|
||||
private void ReadSection ()
|
||||
{
|
||||
int ch = -1;
|
||||
iniType = IniType.Section;
|
||||
ch = ReadChar (); // consume "["
|
||||
|
||||
while (true)
|
||||
{
|
||||
ch = PeekChar ();
|
||||
if (ch == ']') {
|
||||
break;
|
||||
}
|
||||
if (EndOfLine (ch)) {
|
||||
throw new IniException (this, "Expected section end (])");
|
||||
}
|
||||
|
||||
this.name.Append ((char)ReadChar ());
|
||||
}
|
||||
|
||||
ConsumeToEnd (); // all after '[' is garbage
|
||||
RemoveTrailingWhitespace (this.name);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks for a comment.
|
||||
/// </summary>
|
||||
private void SearchForComment ()
|
||||
{
|
||||
int ch = ReadChar ();
|
||||
|
||||
while (!EndOfLine (ch))
|
||||
{
|
||||
if (IsComment (ch)) {
|
||||
if (ignoreComments) {
|
||||
ConsumeToEnd ();
|
||||
} else {
|
||||
ReadComment ();
|
||||
}
|
||||
break;
|
||||
}
|
||||
ch = ReadChar ();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Consumes all data until the end of a line.
|
||||
/// </summary>
|
||||
private void ConsumeToEnd ()
|
||||
{
|
||||
int ch = -1;
|
||||
|
||||
do
|
||||
{
|
||||
ch = ReadChar ();
|
||||
} while (!EndOfLine (ch));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns and consumes the next character from the stream.
|
||||
/// </summary>
|
||||
private int ReadChar ()
|
||||
{
|
||||
int result = textReader.Read ();
|
||||
|
||||
if (result == '\n') {
|
||||
lineNumber++;
|
||||
column = 1;
|
||||
} else {
|
||||
column++;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns the next upcoming character from the stream.
|
||||
/// </summary>
|
||||
private int PeekChar ()
|
||||
{
|
||||
return textReader.Peek ();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns true if a comment character is found.
|
||||
/// </summary>
|
||||
private bool IsComment (int ch)
|
||||
{
|
||||
return HasCharacter (commentDelimiters, ch);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns true if character is an assign character.
|
||||
/// </summary>
|
||||
private bool IsAssign (int ch)
|
||||
{
|
||||
return HasCharacter (assignDelimiters, ch);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns true if the character is found in the given array.
|
||||
/// </summary>
|
||||
private bool HasCharacter (char[] characters, int ch)
|
||||
{
|
||||
bool result = false;
|
||||
|
||||
for (int i = 0; i < characters.Length; i++)
|
||||
{
|
||||
if (ch == characters[i])
|
||||
{
|
||||
result = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns true if a value is whitespace.
|
||||
/// </summary>
|
||||
private bool IsWhitespace (int ch)
|
||||
{
|
||||
return ch == 0x20 || ch == 0x9 || ch == 0xD || ch == 0xA;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Skips all whitespace.
|
||||
/// </summary>
|
||||
private void SkipWhitespace ()
|
||||
{
|
||||
while (IsWhitespace (PeekChar ()))
|
||||
{
|
||||
if (EndOfLine (PeekChar ())) {
|
||||
break;
|
||||
}
|
||||
|
||||
ReadChar ();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns true if an end of line is found. End of line
|
||||
/// includes both an end of line or end of file.
|
||||
/// </summary>
|
||||
private bool EndOfLine (int ch)
|
||||
{
|
||||
return (ch == '\n' || ch == -1);
|
||||
}
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
155
ExtensionLoader/Nini/Ini/IniSection.cs
Normal file
155
ExtensionLoader/Nini/Ini/IniSection.cs
Normal file
@@ -0,0 +1,155 @@
|
||||
#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.Collections;
|
||||
using Nini.Util;
|
||||
|
||||
namespace Nini.Ini
|
||||
{
|
||||
/// <include file='IniSection.xml' path='//Class[@name="IniSection"]/docs/*' />
|
||||
public class IniSection
|
||||
{
|
||||
#region Private variables
|
||||
OrderedList configList = new OrderedList ();
|
||||
string name = "";
|
||||
string comment = null;
|
||||
int commentCount = 0;
|
||||
#endregion
|
||||
|
||||
#region Constructors
|
||||
/// <include file='IniSection.xml' path='//Constructor[@name="ConstructorComment"]/docs/*' />
|
||||
public IniSection (string name, string comment)
|
||||
{
|
||||
this.name = name;
|
||||
this.comment = comment;
|
||||
}
|
||||
|
||||
/// <include file='IniSection.xml' path='//Constructor[@name="Constructor"]/docs/*' />
|
||||
public IniSection (string name)
|
||||
: this (name, null)
|
||||
{
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region Public properties
|
||||
/// <include file='IniSection.xml' path='//Property[@name="Name"]/docs/*' />
|
||||
public string Name
|
||||
{
|
||||
get { return name; }
|
||||
}
|
||||
|
||||
/// <include file='IniSection.xml' path='//Property[@name="Comment"]/docs/*' />
|
||||
public string Comment
|
||||
{
|
||||
get { return comment; }
|
||||
}
|
||||
|
||||
/// <include file='IniSection.xml' path='//Property[@name="ItemCount"]/docs/*' />
|
||||
public int ItemCount
|
||||
{
|
||||
get { return configList.Count; }
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region Public methods
|
||||
|
||||
/// <include file='IniSection.xml' path='//Method[@name="GetValue"]/docs/*' />
|
||||
public string GetValue (string key)
|
||||
{
|
||||
string result = null;
|
||||
|
||||
if (Contains (key)) {
|
||||
IniItem item = (IniItem)configList[key];
|
||||
result = item.Value;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/// <include file='IniSection.xml' path='//Method[@name="GetItem"]/docs/*' />
|
||||
public IniItem GetItem (int index)
|
||||
{
|
||||
return (IniItem)configList[index];
|
||||
}
|
||||
|
||||
/// <include file='IniSection.xml' path='//Method[@name="GetKeys"]/docs/*' />
|
||||
public string[] GetKeys ()
|
||||
{
|
||||
ArrayList list = new ArrayList ();
|
||||
IniItem item = null;
|
||||
|
||||
for (int i = 0; i < configList.Count; i++)
|
||||
{
|
||||
item = (IniItem)configList[i];
|
||||
if (item.Type == IniType.Key) {
|
||||
list.Add (item.Name);
|
||||
}
|
||||
}
|
||||
string[] result = new string[list.Count];
|
||||
list.CopyTo (result, 0);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/// <include file='IniSection.xml' path='//Method[@name="Contains"]/docs/*' />
|
||||
public bool Contains (string key)
|
||||
{
|
||||
return (configList[key] != null);
|
||||
}
|
||||
|
||||
/// <include file='IniSection.xml' path='//Method[@name="SetKeyComment"]/docs/*' />
|
||||
public void Set (string key, string value, string comment)
|
||||
{
|
||||
IniItem item = null;
|
||||
|
||||
if (Contains (key)) {
|
||||
item = (IniItem)configList[key];
|
||||
item.Value = value;
|
||||
item.Comment = comment;
|
||||
} else {
|
||||
item = new IniItem (key, value, IniType.Key, comment);
|
||||
configList.Add (key, item);
|
||||
}
|
||||
}
|
||||
|
||||
/// <include file='IniSection.xml' path='//Method[@name="SetKey"]/docs/*' />
|
||||
public void Set (string key, string value)
|
||||
{
|
||||
Set (key, value, null);
|
||||
}
|
||||
|
||||
/// <include file='IniSection.xml' path='//Method[@name="SetComment"]/docs/*' />
|
||||
public void Set (string comment)
|
||||
{
|
||||
string name = "#comment" + commentCount;
|
||||
IniItem item = new IniItem (name, null,
|
||||
IniType.Empty, comment);
|
||||
configList.Add (name, item);
|
||||
|
||||
commentCount++;
|
||||
}
|
||||
|
||||
/// <include file='IniSection.xml' path='//Method[@name="SetNoComment"]/docs/*' />
|
||||
public void Set ()
|
||||
{
|
||||
Set (null);
|
||||
}
|
||||
|
||||
/// <include file='IniSection.xml' path='//Method[@name="Remove"]/docs/*' />
|
||||
public void Remove (string key)
|
||||
{
|
||||
if (Contains (key)) {
|
||||
configList.Remove (key);
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
95
ExtensionLoader/Nini/Ini/IniSectionCollection.cs
Normal file
95
ExtensionLoader/Nini/Ini/IniSectionCollection.cs
Normal file
@@ -0,0 +1,95 @@
|
||||
#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.Collections;
|
||||
using Nini.Util;
|
||||
|
||||
namespace Nini.Ini
|
||||
{
|
||||
/// <include file='IniSectionCollection.xml' path='//Class[@name="IniSectionCollection"]/docs/*' />
|
||||
public class IniSectionCollection : ICollection, IEnumerable
|
||||
{
|
||||
#region Private variables
|
||||
OrderedList list = new OrderedList ();
|
||||
#endregion
|
||||
|
||||
#region Public properties
|
||||
/// <include file='IniSectionCollection.xml' path='//Property[@name="ItemIndex"]/docs/*' />
|
||||
public IniSection this[int index]
|
||||
{
|
||||
get { return (IniSection)list[index]; }
|
||||
}
|
||||
|
||||
/// <include file='IniSectionCollection.xml' path='//Property[@name="ItemName"]/docs/*' />
|
||||
public IniSection this[string configName]
|
||||
{
|
||||
get { return (IniSection)list[configName]; }
|
||||
}
|
||||
|
||||
/// <include file='IniSectionCollection.xml' path='//Property[@name="Count"]/docs/*' />
|
||||
public int Count
|
||||
{
|
||||
get { return list.Count; }
|
||||
}
|
||||
|
||||
/// <include file='IniSectionCollection.xml' path='//Property[@name="SyncRoot"]/docs/*' />
|
||||
public object SyncRoot
|
||||
{
|
||||
get { return list.SyncRoot; }
|
||||
}
|
||||
|
||||
/// <include file='IniSectionCollection.xml' path='//Property[@name="IsSynchronized"]/docs/*' />
|
||||
public bool IsSynchronized
|
||||
{
|
||||
get { return list.IsSynchronized; }
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region Public methods
|
||||
/// <include file='IniSectionCollection.xml' path='//Method[@name="Add"]/docs/*' />
|
||||
public void Add (IniSection section)
|
||||
{
|
||||
if (list.Contains (section)) {
|
||||
throw new ArgumentException ("IniSection already exists");
|
||||
}
|
||||
|
||||
list.Add (section.Name, section);
|
||||
}
|
||||
|
||||
/// <include file='IniSectionCollection.xml' path='//Method[@name="Remove"]/docs/*' />
|
||||
public void Remove (string config)
|
||||
{
|
||||
list.Remove (config);
|
||||
}
|
||||
|
||||
/// <include file='IniSectionCollection.xml' path='//Method[@name="CopyTo"]/docs/*' />
|
||||
public void CopyTo (Array array, int index)
|
||||
{
|
||||
list.CopyTo (array, index);
|
||||
}
|
||||
|
||||
/// <include file='IniSectionCollection.xml' path='//Method[@name="CopyToStrong"]/docs/*' />
|
||||
public void CopyTo (IniSection[] array, int index)
|
||||
{
|
||||
((ICollection)list).CopyTo (array, index);
|
||||
}
|
||||
|
||||
/// <include file='IniSectionCollection.xml' path='//Method[@name="GetEnumerator"]/docs/*' />
|
||||
public IEnumerator GetEnumerator ()
|
||||
{
|
||||
return list.GetEnumerator ();
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region Private methods
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
308
ExtensionLoader/Nini/Ini/IniWriter.cs
Normal file
308
ExtensionLoader/Nini/Ini/IniWriter.cs
Normal file
@@ -0,0 +1,308 @@
|
||||
#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.Text;
|
||||
|
||||
namespace Nini.Ini
|
||||
{
|
||||
#region IniWriteState enumeration
|
||||
/// <include file='IniWriter.xml' path='//Enum[@name="IniWriteState"]/docs/*' />
|
||||
public enum IniWriteState : int
|
||||
{
|
||||
/// <include file='IniWriter.xml' path='//Enum[@name="IniWriteState"]/Value[@name="Start"]/docs/*' />
|
||||
Start,
|
||||
/// <include file='IniWriter.xml' path='//Enum[@name="IniWriteState"]/Value[@name="BeforeFirstSection"]/docs/*' />
|
||||
BeforeFirstSection,
|
||||
/// <include file='IniWriter.xml' path='//Enum[@name="IniWriteState"]/Value[@name="Section"]/docs/*' />
|
||||
Section,
|
||||
/// <include file='IniWriter.xml' path='//Enum[@name="IniWriteState"]/Value[@name="Closed"]/docs/*' />
|
||||
Closed
|
||||
};
|
||||
#endregion
|
||||
|
||||
/// <include file='IniWriter.xml' path='//Class[@name="IniWriter"]/docs/*' />
|
||||
public class IniWriter : IDisposable
|
||||
{
|
||||
#region Private variables
|
||||
int indentation = 0;
|
||||
bool useValueQuotes = false;
|
||||
IniWriteState writeState = IniWriteState.Start;
|
||||
char commentDelimiter = ';';
|
||||
char assignDelimiter = '=';
|
||||
TextWriter textWriter = null;
|
||||
string eol = "\r\n";
|
||||
StringBuilder indentationBuffer = new StringBuilder ();
|
||||
Stream baseStream = null;
|
||||
bool disposed = false;
|
||||
#endregion
|
||||
|
||||
#region Public properties
|
||||
/// <include file='IniWriter.xml' path='//Property[@name="Indentation"]/docs/*' />
|
||||
public int Indentation
|
||||
{
|
||||
get { return indentation; }
|
||||
set
|
||||
{
|
||||
if (value < 0)
|
||||
throw new ArgumentException ("Negative values are illegal");
|
||||
|
||||
indentation = value;
|
||||
indentationBuffer.Remove(0, indentationBuffer.Length);
|
||||
for (int i = 0; i < value; i++)
|
||||
indentationBuffer.Append (' ');
|
||||
}
|
||||
}
|
||||
|
||||
/// <include file='IniWriter.xml' path='//Property[@name="UseValueQuotes"]/docs/*' />
|
||||
public bool UseValueQuotes
|
||||
{
|
||||
get { return useValueQuotes; }
|
||||
set { useValueQuotes = value; }
|
||||
}
|
||||
|
||||
/// <include file='IniWriter.xml' path='//Property[@name="WriteState"]/docs/*' />
|
||||
public IniWriteState WriteState
|
||||
{
|
||||
get { return writeState; }
|
||||
}
|
||||
|
||||
/// <include file='IniWriter.xml' path='//Property[@name="CommentDelimiter"]/docs/*' />
|
||||
public char CommentDelimiter
|
||||
{
|
||||
get { return commentDelimiter; }
|
||||
set { commentDelimiter = value; }
|
||||
}
|
||||
|
||||
/// <include file='IniWriter.xml' path='//Property[@name="AssignDelimiter"]/docs/*' />
|
||||
public char AssignDelimiter
|
||||
{
|
||||
get { return assignDelimiter; }
|
||||
set { assignDelimiter = value; }
|
||||
}
|
||||
|
||||
/// <include file='IniWriter.xml' path='//Property[@name="BaseStream"]/docs/*' />
|
||||
public Stream BaseStream
|
||||
{
|
||||
get { return baseStream; }
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region Constructors
|
||||
/// <include file='IniWriter.xml' path='//Constructor[@name="ConstructorPath"]/docs/*' />
|
||||
public IniWriter(string filePath)
|
||||
: this (new FileStream (filePath, FileMode.Create, FileAccess.Write, FileShare.None))
|
||||
{
|
||||
}
|
||||
|
||||
/// <include file='IniWriter.xml' path='//Constructor[@name="ConstructorTextWriter"]/docs/*' />
|
||||
public IniWriter (TextWriter writer)
|
||||
{
|
||||
textWriter = writer;
|
||||
StreamWriter streamWriter = writer as StreamWriter;
|
||||
if (streamWriter != null) {
|
||||
baseStream = streamWriter.BaseStream;
|
||||
}
|
||||
}
|
||||
|
||||
/// <include file='IniWriter.xml' path='//Constructor[@name="ConstructorStream"]/docs/*' />
|
||||
public IniWriter (Stream stream)
|
||||
: this (new StreamWriter (stream))
|
||||
{
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region Public methods
|
||||
/// <include file='IniWriter.xml' path='//Method[@name="Close"]/docs/*' />
|
||||
public void Close ()
|
||||
{
|
||||
textWriter.Close ();
|
||||
writeState = IniWriteState.Closed;
|
||||
}
|
||||
|
||||
/// <include file='IniWriter.xml' path='//Method[@name="Flush"]/docs/*' />
|
||||
public void Flush ()
|
||||
{
|
||||
textWriter.Flush ();
|
||||
}
|
||||
|
||||
/// <include file='IniWriter.xml' path='//Method[@name="ToString"]/docs/*' />
|
||||
public override string ToString ()
|
||||
{
|
||||
return textWriter.ToString ();
|
||||
}
|
||||
|
||||
/// <include file='IniWriter.xml' path='//Method[@name="WriteSection"]/docs/*' />
|
||||
public void WriteSection (string section)
|
||||
{
|
||||
ValidateState ();
|
||||
writeState = IniWriteState.Section;
|
||||
WriteLine ("[" + section + "]");
|
||||
}
|
||||
|
||||
/// <include file='IniWriter.xml' path='//Method[@name="WriteSectionComment"]/docs/*' />
|
||||
public void WriteSection (string section, string comment)
|
||||
{
|
||||
ValidateState ();
|
||||
writeState = IniWriteState.Section;
|
||||
WriteLine ("[" + section + "]" + Comment(comment));
|
||||
}
|
||||
|
||||
/// <include file='IniWriter.xml' path='//Method[@name="WriteKey"]/docs/*' />
|
||||
public void WriteKey (string key, string value)
|
||||
{
|
||||
ValidateStateKey ();
|
||||
WriteLine (key + " " + assignDelimiter + " " + GetKeyValue (value));
|
||||
}
|
||||
|
||||
/// <include file='IniWriter.xml' path='//Method[@name="WriteKeyComment"]/docs/*' />
|
||||
public void WriteKey (string key, string value, string comment)
|
||||
{
|
||||
ValidateStateKey ();
|
||||
WriteLine (key + " " + assignDelimiter + " " + GetKeyValue (value) + Comment (comment));
|
||||
}
|
||||
|
||||
/// <include file='IniWriter.xml' path='//Method[@name="WriteEmpty"]/docs/*' />
|
||||
public void WriteEmpty ()
|
||||
{
|
||||
ValidateState ();
|
||||
if (writeState == IniWriteState.Start) {
|
||||
writeState = IniWriteState.BeforeFirstSection;
|
||||
}
|
||||
WriteLine ("");
|
||||
}
|
||||
|
||||
/// <include file='IniWriter.xml' path='//Method[@name="WriteEmptyComment"]/docs/*' />
|
||||
public void WriteEmpty (string comment)
|
||||
{
|
||||
ValidateState ();
|
||||
if (writeState == IniWriteState.Start) {
|
||||
writeState = IniWriteState.BeforeFirstSection;
|
||||
}
|
||||
if (comment == null) {
|
||||
WriteLine ("");
|
||||
} else {
|
||||
WriteLine (commentDelimiter + " " + comment);
|
||||
}
|
||||
}
|
||||
|
||||
/// <include file='IniWriter.xml' path='//Method[@name="Dispose"]/docs/*' />
|
||||
public void Dispose ()
|
||||
{
|
||||
Dispose (true);
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region Protected methods
|
||||
/// <include file='IniWriter.xml' path='//Method[@name="DisposeBoolean"]/docs/*' />
|
||||
protected virtual void Dispose (bool disposing)
|
||||
{
|
||||
if (!disposed)
|
||||
{
|
||||
textWriter.Close ();
|
||||
baseStream.Close ();
|
||||
disposed = true;
|
||||
|
||||
if (disposing)
|
||||
{
|
||||
GC.SuppressFinalize (this);
|
||||
}
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region Private methods
|
||||
/// <summary>
|
||||
/// Destructor.
|
||||
/// </summary>
|
||||
~IniWriter ()
|
||||
{
|
||||
Dispose (false);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns the value of a key.
|
||||
/// </summary>
|
||||
private string GetKeyValue (string text)
|
||||
{
|
||||
string result;
|
||||
|
||||
if (useValueQuotes) {
|
||||
result = MassageValue ('"' + text + '"');
|
||||
} else {
|
||||
result = MassageValue (text);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Validates whether a key can be written.
|
||||
/// </summary>
|
||||
private void ValidateStateKey ()
|
||||
{
|
||||
ValidateState ();
|
||||
|
||||
switch (writeState)
|
||||
{
|
||||
case IniWriteState.BeforeFirstSection:
|
||||
case IniWriteState.Start:
|
||||
throw new InvalidOperationException ("The WriteState is not Section");
|
||||
case IniWriteState.Closed:
|
||||
throw new InvalidOperationException ("The writer is closed");
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Validates the state to determine if the item can be written.
|
||||
/// </summary>
|
||||
private void ValidateState ()
|
||||
{
|
||||
if (writeState == IniWriteState.Closed) {
|
||||
throw new InvalidOperationException ("The writer is closed");
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns a formatted comment.
|
||||
/// </summary>
|
||||
private string Comment (string text)
|
||||
{
|
||||
return (text == null) ? "" : (" " + commentDelimiter + " " + text);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Writes data to the writer.
|
||||
/// </summary>
|
||||
private void Write (string value)
|
||||
{
|
||||
textWriter.Write (indentationBuffer.ToString () + value);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Writes a full line to the writer.
|
||||
/// </summary>
|
||||
private void WriteLine (string value)
|
||||
{
|
||||
Write (value + eol);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Fixes the incoming value to prevent illegal characters from
|
||||
/// hurting the integrity of the INI file.
|
||||
/// </summary>
|
||||
private string MassageValue (string text)
|
||||
{
|
||||
return text.Replace ("\n", "");
|
||||
}
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
199
ExtensionLoader/Nini/Util/OrderedList.cs
Normal file
199
ExtensionLoader/Nini/Util/OrderedList.cs
Normal file
@@ -0,0 +1,199 @@
|
||||
using System;
|
||||
using System.Collections;
|
||||
|
||||
namespace Nini.Util
|
||||
{
|
||||
//[Serializable]
|
||||
/// <include file='OrderedList.xml' path='//Class[@name="OrderedList"]/docs/*' />
|
||||
public class OrderedList : ICollection, IDictionary, IEnumerable
|
||||
{
|
||||
#region Private variables
|
||||
Hashtable table = new Hashtable ();
|
||||
ArrayList list = new ArrayList ();
|
||||
#endregion
|
||||
|
||||
#region Public properties
|
||||
/// <include file='OrderedList.xml' path='//Property[@name="Count"]/docs/*' />
|
||||
public int Count
|
||||
{
|
||||
get { return list.Count; }
|
||||
}
|
||||
|
||||
/// <include file='OrderedList.xml' path='//Property[@name="IsFixedSize"]/docs/*' />
|
||||
public bool IsFixedSize
|
||||
{
|
||||
get { return false; }
|
||||
}
|
||||
|
||||
/// <include file='OrderedList.xml' path='//Property[@name="IsReadOnly"]/docs/*' />
|
||||
public bool IsReadOnly
|
||||
{
|
||||
get { return false; }
|
||||
}
|
||||
|
||||
/// <include file='OrderedList.xml' path='//Property[@name="IsSynchronized"]/docs/*' />
|
||||
public bool IsSynchronized
|
||||
{
|
||||
get { return false; }
|
||||
}
|
||||
|
||||
/// <include file='OrderedList.xml' path='//Property[@name="ItemIndex"]/docs/*' />
|
||||
public object this[int index]
|
||||
{
|
||||
get { return ((DictionaryEntry) list[index]).Value; }
|
||||
set
|
||||
{
|
||||
if (index < 0 || index >= Count)
|
||||
throw new ArgumentOutOfRangeException ("index");
|
||||
|
||||
object key = ((DictionaryEntry) list[index]).Key;
|
||||
list[index] = new DictionaryEntry (key, value);
|
||||
table[key] = value;
|
||||
}
|
||||
}
|
||||
|
||||
/// <include file='OrderedList.xml' path='//Property[@name="ItemKey"]/docs/*' />
|
||||
public object this[object key]
|
||||
{
|
||||
get { return table[key]; }
|
||||
set
|
||||
{
|
||||
if (table.Contains (key))
|
||||
{
|
||||
table[key] = value;
|
||||
table[IndexOf (key)] = new DictionaryEntry (key, value);
|
||||
return;
|
||||
}
|
||||
Add (key, value);
|
||||
}
|
||||
}
|
||||
|
||||
/// <include file='OrderedList.xml' path='//Property[@name="Keys"]/docs/*' />
|
||||
public ICollection Keys
|
||||
{
|
||||
get
|
||||
{
|
||||
ArrayList retList = new ArrayList ();
|
||||
for (int i = 0; i < list.Count; i++)
|
||||
{
|
||||
retList.Add ( ((DictionaryEntry)list[i]).Key );
|
||||
}
|
||||
return retList;
|
||||
}
|
||||
}
|
||||
|
||||
/// <include file='OrderedList.xml' path='//Property[@name="Values"]/docs/*' />
|
||||
public ICollection Values
|
||||
{
|
||||
get
|
||||
{
|
||||
ArrayList retList = new ArrayList ();
|
||||
for (int i = 0; i < list.Count; i++)
|
||||
{
|
||||
retList.Add ( ((DictionaryEntry)list[i]).Value );
|
||||
}
|
||||
return retList;
|
||||
}
|
||||
}
|
||||
|
||||
/// <include file='OrderedList.xml' path='//Property[@name="SyncRoot"]/docs/*' />
|
||||
public object SyncRoot
|
||||
{
|
||||
get { return this; }
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region Public methods
|
||||
/// <include file='OrderedList.xml' path='//Method[@name="Add"]/docs/*' />
|
||||
public void Add (object key, object value)
|
||||
{
|
||||
table.Add (key, value);
|
||||
list.Add (new DictionaryEntry (key, value));
|
||||
}
|
||||
|
||||
/// <include file='OrderedList.xml' path='//Method[@name="Clear"]/docs/*' />
|
||||
public void Clear ()
|
||||
{
|
||||
table.Clear ();
|
||||
list.Clear ();
|
||||
}
|
||||
|
||||
/// <include file='OrderedList.xml' path='//Method[@name="Contains"]/docs/*' />
|
||||
public bool Contains (object key)
|
||||
{
|
||||
return table.Contains (key);
|
||||
}
|
||||
|
||||
/// <include file='OrderedList.xml' path='//Method[@name="CopyTo"]/docs/*' />
|
||||
public void CopyTo (Array array, int index)
|
||||
{
|
||||
table.CopyTo (array, index);
|
||||
}
|
||||
|
||||
/// <include file='OrderedList.xml' path='//Method[@name="CopyToStrong"]/docs/*' />
|
||||
public void CopyTo (DictionaryEntry[] array, int index)
|
||||
{
|
||||
table.CopyTo (array, index);
|
||||
}
|
||||
|
||||
/// <include file='OrderedList.xml' path='//Method[@name="Insert"]/docs/*' />
|
||||
public void Insert (int index, object key, object value)
|
||||
{
|
||||
if (index > Count)
|
||||
throw new ArgumentOutOfRangeException ("index");
|
||||
|
||||
table.Add (key, value);
|
||||
list.Insert (index, new DictionaryEntry (key, value));
|
||||
}
|
||||
|
||||
/// <include file='OrderedList.xml' path='//Method[@name="Remove"]/docs/*' />
|
||||
public void Remove (object key)
|
||||
{
|
||||
table.Remove (key);
|
||||
list.RemoveAt (IndexOf (key));
|
||||
}
|
||||
|
||||
/// <include file='OrderedList.xml' path='//Method[@name="RemoveAt"]/docs/*' />
|
||||
public void RemoveAt (int index)
|
||||
{
|
||||
if (index >= Count)
|
||||
throw new ArgumentOutOfRangeException ("index");
|
||||
|
||||
table.Remove ( ((DictionaryEntry)list[index]).Key );
|
||||
list.RemoveAt (index);
|
||||
}
|
||||
|
||||
/// <include file='OrderedList.xml' path='//Method[@name="GetEnumerator"]/docs/*' />
|
||||
public IEnumerator GetEnumerator ()
|
||||
{
|
||||
return new OrderedListEnumerator (list);
|
||||
}
|
||||
|
||||
/// <include file='OrderedList.xml' path='//Method[@name="GetDictionaryEnumerator"]/docs/*' />
|
||||
IDictionaryEnumerator IDictionary.GetEnumerator ()
|
||||
{
|
||||
return new OrderedListEnumerator (list);
|
||||
}
|
||||
|
||||
/// <include file='OrderedList.xml' path='//Method[@name="GetIEnumerator"]/docs/*' />
|
||||
IEnumerator IEnumerable.GetEnumerator ()
|
||||
{
|
||||
return new OrderedListEnumerator (list);
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region Private variables
|
||||
private int IndexOf (object key)
|
||||
{
|
||||
for (int i = 0; i < list.Count; i++)
|
||||
{
|
||||
if (((DictionaryEntry) list[i]).Key.Equals (key))
|
||||
{
|
||||
return i;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
86
ExtensionLoader/Nini/Util/OrderedListEnumerator.cs
Normal file
86
ExtensionLoader/Nini/Util/OrderedListEnumerator.cs
Normal file
@@ -0,0 +1,86 @@
|
||||
using System;
|
||||
using System.Collections;
|
||||
|
||||
namespace Nini.Util
|
||||
{
|
||||
/// <include file='OrderedListEnumerator.xml' path='//Class[@name="OrderedListEnumerator"]/docs/*' />
|
||||
public class OrderedListEnumerator : IDictionaryEnumerator
|
||||
{
|
||||
#region Private variables
|
||||
int index = -1;
|
||||
ArrayList list;
|
||||
#endregion
|
||||
|
||||
#region Constructors
|
||||
/// <summary>
|
||||
/// Instantiates an ordered list enumerator with an ArrayList.
|
||||
/// </summary>
|
||||
internal OrderedListEnumerator (ArrayList arrayList)
|
||||
{
|
||||
list = arrayList;
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region Public properties
|
||||
/// <include file='OrderedListEnumerator.xml' path='//Property[@name="Current"]/docs/*' />
|
||||
object IEnumerator.Current
|
||||
{
|
||||
get
|
||||
{
|
||||
if (index < 0 || index >= list.Count)
|
||||
throw new InvalidOperationException ();
|
||||
|
||||
return list[index];
|
||||
}
|
||||
}
|
||||
|
||||
/// <include file='OrderedListEnumerator.xml' path='//Property[@name="CurrentStrong"]/docs/*' />
|
||||
public DictionaryEntry Current
|
||||
{
|
||||
get
|
||||
{
|
||||
if (index < 0 || index >= list.Count)
|
||||
throw new InvalidOperationException ();
|
||||
|
||||
return (DictionaryEntry)list[index];
|
||||
}
|
||||
}
|
||||
|
||||
/// <include file='OrderedListEnumerator.xml' path='//Property[@name="Entry"]/docs/*' />
|
||||
public DictionaryEntry Entry
|
||||
{
|
||||
get { return (DictionaryEntry) Current; }
|
||||
}
|
||||
|
||||
/// <include file='OrderedListEnumerator.xml' path='//Property[@name="Key"]/docs/*' />
|
||||
public object Key
|
||||
{
|
||||
get { return Entry.Key; }
|
||||
}
|
||||
|
||||
/// <include file='OrderedListEnumerator.xml' path='//Property[@name="Value"]/docs/*' />
|
||||
public object Value
|
||||
{
|
||||
get { return Entry.Value; }
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region Public methods
|
||||
/// <include file='OrderedListEnumerator.xml' path='//Method[@name="MoveNext"]/docs/*' />
|
||||
public bool MoveNext ()
|
||||
{
|
||||
index++;
|
||||
if (index >= list.Count)
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/// <include file='OrderedListEnumerator.xml' path='//Method[@name="Reset"]/docs/*' />
|
||||
public void Reset ()
|
||||
{
|
||||
index = -1;
|
||||
}
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
199
ExtensionLoader/Util/OrderedList.cs
Normal file
199
ExtensionLoader/Util/OrderedList.cs
Normal file
@@ -0,0 +1,199 @@
|
||||
using System;
|
||||
using System.Collections;
|
||||
|
||||
namespace ExtensionLoader.Util
|
||||
{
|
||||
//[Serializable]
|
||||
/// <include file='OrderedList.xml' path='//Class[@name="OrderedList"]/docs/*' />
|
||||
public class OrderedList : ICollection, IDictionary, IEnumerable
|
||||
{
|
||||
#region Private variables
|
||||
Hashtable table = new Hashtable ();
|
||||
ArrayList list = new ArrayList ();
|
||||
#endregion
|
||||
|
||||
#region Public properties
|
||||
/// <include file='OrderedList.xml' path='//Property[@name="Count"]/docs/*' />
|
||||
public int Count
|
||||
{
|
||||
get { return list.Count; }
|
||||
}
|
||||
|
||||
/// <include file='OrderedList.xml' path='//Property[@name="IsFixedSize"]/docs/*' />
|
||||
public bool IsFixedSize
|
||||
{
|
||||
get { return false; }
|
||||
}
|
||||
|
||||
/// <include file='OrderedList.xml' path='//Property[@name="IsReadOnly"]/docs/*' />
|
||||
public bool IsReadOnly
|
||||
{
|
||||
get { return false; }
|
||||
}
|
||||
|
||||
/// <include file='OrderedList.xml' path='//Property[@name="IsSynchronized"]/docs/*' />
|
||||
public bool IsSynchronized
|
||||
{
|
||||
get { return false; }
|
||||
}
|
||||
|
||||
/// <include file='OrderedList.xml' path='//Property[@name="ItemIndex"]/docs/*' />
|
||||
public object this[int index]
|
||||
{
|
||||
get { return ((DictionaryEntry) list[index]).Value; }
|
||||
set
|
||||
{
|
||||
if (index < 0 || index >= Count)
|
||||
throw new ArgumentOutOfRangeException ("index");
|
||||
|
||||
object key = ((DictionaryEntry) list[index]).Key;
|
||||
list[index] = new DictionaryEntry (key, value);
|
||||
table[key] = value;
|
||||
}
|
||||
}
|
||||
|
||||
/// <include file='OrderedList.xml' path='//Property[@name="ItemKey"]/docs/*' />
|
||||
public object this[object key]
|
||||
{
|
||||
get { return table[key]; }
|
||||
set
|
||||
{
|
||||
if (table.Contains (key))
|
||||
{
|
||||
table[key] = value;
|
||||
table[IndexOf (key)] = new DictionaryEntry (key, value);
|
||||
return;
|
||||
}
|
||||
Add (key, value);
|
||||
}
|
||||
}
|
||||
|
||||
/// <include file='OrderedList.xml' path='//Property[@name="Keys"]/docs/*' />
|
||||
public ICollection Keys
|
||||
{
|
||||
get
|
||||
{
|
||||
ArrayList retList = new ArrayList ();
|
||||
for (int i = 0; i < list.Count; i++)
|
||||
{
|
||||
retList.Add ( ((DictionaryEntry)list[i]).Key );
|
||||
}
|
||||
return retList;
|
||||
}
|
||||
}
|
||||
|
||||
/// <include file='OrderedList.xml' path='//Property[@name="Values"]/docs/*' />
|
||||
public ICollection Values
|
||||
{
|
||||
get
|
||||
{
|
||||
ArrayList retList = new ArrayList ();
|
||||
for (int i = 0; i < list.Count; i++)
|
||||
{
|
||||
retList.Add ( ((DictionaryEntry)list[i]).Value );
|
||||
}
|
||||
return retList;
|
||||
}
|
||||
}
|
||||
|
||||
/// <include file='OrderedList.xml' path='//Property[@name="SyncRoot"]/docs/*' />
|
||||
public object SyncRoot
|
||||
{
|
||||
get { return this; }
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region Public methods
|
||||
/// <include file='OrderedList.xml' path='//Method[@name="Add"]/docs/*' />
|
||||
public void Add (object key, object value)
|
||||
{
|
||||
table.Add (key, value);
|
||||
list.Add (new DictionaryEntry (key, value));
|
||||
}
|
||||
|
||||
/// <include file='OrderedList.xml' path='//Method[@name="Clear"]/docs/*' />
|
||||
public void Clear ()
|
||||
{
|
||||
table.Clear ();
|
||||
list.Clear ();
|
||||
}
|
||||
|
||||
/// <include file='OrderedList.xml' path='//Method[@name="Contains"]/docs/*' />
|
||||
public bool Contains (object key)
|
||||
{
|
||||
return table.Contains (key);
|
||||
}
|
||||
|
||||
/// <include file='OrderedList.xml' path='//Method[@name="CopyTo"]/docs/*' />
|
||||
public void CopyTo (Array array, int index)
|
||||
{
|
||||
table.CopyTo (array, index);
|
||||
}
|
||||
|
||||
/// <include file='OrderedList.xml' path='//Method[@name="CopyToStrong"]/docs/*' />
|
||||
public void CopyTo (DictionaryEntry[] array, int index)
|
||||
{
|
||||
table.CopyTo (array, index);
|
||||
}
|
||||
|
||||
/// <include file='OrderedList.xml' path='//Method[@name="Insert"]/docs/*' />
|
||||
public void Insert (int index, object key, object value)
|
||||
{
|
||||
if (index > Count)
|
||||
throw new ArgumentOutOfRangeException ("index");
|
||||
|
||||
table.Add (key, value);
|
||||
list.Insert (index, new DictionaryEntry (key, value));
|
||||
}
|
||||
|
||||
/// <include file='OrderedList.xml' path='//Method[@name="Remove"]/docs/*' />
|
||||
public void Remove (object key)
|
||||
{
|
||||
table.Remove (key);
|
||||
list.RemoveAt (IndexOf (key));
|
||||
}
|
||||
|
||||
/// <include file='OrderedList.xml' path='//Method[@name="RemoveAt"]/docs/*' />
|
||||
public void RemoveAt (int index)
|
||||
{
|
||||
if (index >= Count)
|
||||
throw new ArgumentOutOfRangeException ("index");
|
||||
|
||||
table.Remove ( ((DictionaryEntry)list[index]).Key );
|
||||
list.RemoveAt (index);
|
||||
}
|
||||
|
||||
/// <include file='OrderedList.xml' path='//Method[@name="GetEnumerator"]/docs/*' />
|
||||
public IEnumerator GetEnumerator ()
|
||||
{
|
||||
return new OrderedListEnumerator (list);
|
||||
}
|
||||
|
||||
/// <include file='OrderedList.xml' path='//Method[@name="GetDictionaryEnumerator"]/docs/*' />
|
||||
IDictionaryEnumerator IDictionary.GetEnumerator ()
|
||||
{
|
||||
return new OrderedListEnumerator (list);
|
||||
}
|
||||
|
||||
/// <include file='OrderedList.xml' path='//Method[@name="GetIEnumerator"]/docs/*' />
|
||||
IEnumerator IEnumerable.GetEnumerator ()
|
||||
{
|
||||
return new OrderedListEnumerator (list);
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region Private variables
|
||||
private int IndexOf (object key)
|
||||
{
|
||||
for (int i = 0; i < list.Count; i++)
|
||||
{
|
||||
if (((DictionaryEntry) list[i]).Key.Equals (key))
|
||||
{
|
||||
return i;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
86
ExtensionLoader/Util/OrderedListEnumerator.cs
Normal file
86
ExtensionLoader/Util/OrderedListEnumerator.cs
Normal file
@@ -0,0 +1,86 @@
|
||||
using System;
|
||||
using System.Collections;
|
||||
|
||||
namespace ExtensionLoader.Util
|
||||
{
|
||||
/// <include file='OrderedListEnumerator.xml' path='//Class[@name="OrderedListEnumerator"]/docs/*' />
|
||||
public class OrderedListEnumerator : IDictionaryEnumerator
|
||||
{
|
||||
#region Private variables
|
||||
int index = -1;
|
||||
ArrayList list;
|
||||
#endregion
|
||||
|
||||
#region Constructors
|
||||
/// <summary>
|
||||
/// Instantiates an ordered list enumerator with an ArrayList.
|
||||
/// </summary>
|
||||
internal OrderedListEnumerator (ArrayList arrayList)
|
||||
{
|
||||
list = arrayList;
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region Public properties
|
||||
/// <include file='OrderedListEnumerator.xml' path='//Property[@name="Current"]/docs/*' />
|
||||
object IEnumerator.Current
|
||||
{
|
||||
get
|
||||
{
|
||||
if (index < 0 || index >= list.Count)
|
||||
throw new InvalidOperationException ();
|
||||
|
||||
return list[index];
|
||||
}
|
||||
}
|
||||
|
||||
/// <include file='OrderedListEnumerator.xml' path='//Property[@name="CurrentStrong"]/docs/*' />
|
||||
public DictionaryEntry Current
|
||||
{
|
||||
get
|
||||
{
|
||||
if (index < 0 || index >= list.Count)
|
||||
throw new InvalidOperationException ();
|
||||
|
||||
return (DictionaryEntry)list[index];
|
||||
}
|
||||
}
|
||||
|
||||
/// <include file='OrderedListEnumerator.xml' path='//Property[@name="Entry"]/docs/*' />
|
||||
public DictionaryEntry Entry
|
||||
{
|
||||
get { return (DictionaryEntry) Current; }
|
||||
}
|
||||
|
||||
/// <include file='OrderedListEnumerator.xml' path='//Property[@name="Key"]/docs/*' />
|
||||
public object Key
|
||||
{
|
||||
get { return Entry.Key; }
|
||||
}
|
||||
|
||||
/// <include file='OrderedListEnumerator.xml' path='//Property[@name="Value"]/docs/*' />
|
||||
public object Value
|
||||
{
|
||||
get { return Entry.Value; }
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region Public methods
|
||||
/// <include file='OrderedListEnumerator.xml' path='//Method[@name="MoveNext"]/docs/*' />
|
||||
public bool MoveNext ()
|
||||
{
|
||||
index++;
|
||||
if (index >= list.Count)
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/// <include file='OrderedListEnumerator.xml' path='//Method[@name="Reset"]/docs/*' />
|
||||
public void Reset ()
|
||||
{
|
||||
index = -1;
|
||||
}
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user