486 lines
10 KiB
C#
486 lines
10 KiB
C#
#region AuthorHeader
|
|
//
|
|
// ConfigParser version 1.2 - utilities version 2.0, by Xanthos
|
|
//
|
|
// Provides for parsing of xml files containing values to be used to set C# variables during
|
|
// initialization of a module. This code will throw exceptions if the data does not match
|
|
// the expected type or number of elements (in the case of arrays) so that the problem can
|
|
// be corrected to avoid potentially catastrophic runtime errors.
|
|
// If the config file does not exist or cannot be read it will simply output an error to the
|
|
// console and continue. In other words - it's ok not to provide a config file.
|
|
//
|
|
#endregion AuthorHeader
|
|
#undef HALT_ON_ERRORS
|
|
using System;
|
|
using System.IO;
|
|
using System.Xml;
|
|
using System.Text;
|
|
using System.Collections;
|
|
using System.Collections.Specialized;
|
|
using Server;
|
|
|
|
namespace Xanthos.Utilities
|
|
{
|
|
public class ConfigParser
|
|
{
|
|
public static Element GetConfig( string filename, string tag )
|
|
{
|
|
Element element = GetConfig( filename );
|
|
|
|
if ( element != null )
|
|
element = GetConfig( element, tag );
|
|
|
|
return element;
|
|
}
|
|
|
|
public static Element GetConfig( string filename )
|
|
{
|
|
XmlTextReader reader = null;
|
|
Element element = null;
|
|
DOMParser parser;
|
|
|
|
try
|
|
{
|
|
Console.WriteLine( "Xanthos.Utilities.ConfigParser attempting to load {0}...", filename );
|
|
reader = new XmlTextReader( filename );
|
|
parser = new DOMParser();
|
|
element = parser.Parse( reader );
|
|
Console.WriteLine( "Xanthos.Utilities.ConfigParser success!" );
|
|
|
|
}
|
|
catch ( Exception exc )
|
|
{
|
|
// Fail gracefully only on errors reading the file
|
|
if ( !( exc is System.IO.IOException ))
|
|
throw;
|
|
|
|
Console.WriteLine( "Xanthos.Utilities.ConfigParser failed." );
|
|
}
|
|
|
|
if ( null != reader )
|
|
reader.Close();
|
|
|
|
return element;
|
|
}
|
|
|
|
public static Element GetConfig( Element element, string tag )
|
|
{
|
|
if ( element.ChildElements.Count > 0 )
|
|
{
|
|
foreach( Element child in element.ChildElements )
|
|
{
|
|
if ( child.TagName == tag )
|
|
return child;
|
|
}
|
|
}
|
|
return null;
|
|
}
|
|
}
|
|
|
|
public class DOMParser
|
|
{
|
|
private Stack m_Elements;
|
|
private Element m_CurrentElement;
|
|
private Element m_RootElement;
|
|
|
|
public DOMParser()
|
|
{
|
|
m_Elements = new Stack();
|
|
m_CurrentElement = null;
|
|
m_RootElement = null;
|
|
}
|
|
|
|
public Element Parse( XmlTextReader reader )
|
|
{
|
|
Element element = null;
|
|
|
|
while ( !reader.EOF )
|
|
{
|
|
reader.Read();
|
|
switch ( reader.NodeType )
|
|
{
|
|
case XmlNodeType.Element :
|
|
element = new Element( reader.LocalName );
|
|
m_CurrentElement = element;
|
|
if ( m_Elements.Count == 0 )
|
|
{
|
|
m_RootElement = element;
|
|
m_Elements.Push( element );
|
|
}
|
|
else
|
|
{
|
|
Element parent = (Element)m_Elements.Peek();
|
|
parent.ChildElements.Add( element );
|
|
|
|
if ( reader.IsEmptyElement )
|
|
break;
|
|
else
|
|
m_Elements.Push( element );
|
|
}
|
|
if ( reader.HasAttributes )
|
|
{
|
|
while( reader.MoveToNextAttribute() )
|
|
{
|
|
m_CurrentElement.setAttribute( reader.Name, reader.Value );
|
|
}
|
|
}
|
|
break;
|
|
case XmlNodeType.Attribute :
|
|
element.setAttribute( reader.Name, reader.Value );
|
|
break;
|
|
case XmlNodeType.EndElement :
|
|
m_Elements.Pop();
|
|
break;
|
|
case XmlNodeType.Text :
|
|
m_CurrentElement.Text = reader.Value;
|
|
break;
|
|
case XmlNodeType.CDATA :
|
|
m_CurrentElement.Text = reader.Value;
|
|
break;
|
|
default :
|
|
// ignore
|
|
break;
|
|
}
|
|
}
|
|
return m_RootElement;
|
|
}
|
|
}
|
|
|
|
public class Elements : CollectionBase
|
|
{
|
|
public Elements()
|
|
{
|
|
}
|
|
|
|
public void Add( Element element )
|
|
{
|
|
List.Add( element );
|
|
}
|
|
|
|
public Element this[ int index ]
|
|
{
|
|
get { return (Element)List[index]; }
|
|
}
|
|
}
|
|
|
|
public class Element
|
|
{
|
|
private String m_TagName;
|
|
private String m_Text;
|
|
private StringDictionary m_Attributes;
|
|
private Elements m_ChildElements;
|
|
|
|
public Element( String tagName )
|
|
{
|
|
m_TagName = tagName;
|
|
m_Attributes = new StringDictionary();
|
|
m_ChildElements = new Elements();
|
|
m_Text = "";
|
|
}
|
|
|
|
public String TagName
|
|
{
|
|
get { return m_TagName; }
|
|
set { m_TagName = value; }
|
|
}
|
|
|
|
public string Text
|
|
{
|
|
get { return m_Text; }
|
|
set { m_Text = value; }
|
|
}
|
|
|
|
public Elements ChildElements
|
|
{
|
|
get { return m_ChildElements; }
|
|
}
|
|
|
|
public StringDictionary Attributes
|
|
{
|
|
get { return m_Attributes; }
|
|
}
|
|
|
|
public String Attribute( String name )
|
|
{
|
|
return (String)m_Attributes[name];
|
|
}
|
|
|
|
public void setAttribute( String name, String value )
|
|
{
|
|
m_Attributes.Add( name, value );
|
|
}
|
|
|
|
#region Xml to data type conversions
|
|
|
|
public bool GetBoolValue( out bool val )
|
|
{
|
|
val = false;
|
|
|
|
try
|
|
{
|
|
if ( null != m_Text && "" != m_Text )
|
|
{
|
|
val = bool.Parse( m_Text );
|
|
return true;
|
|
}
|
|
}
|
|
catch ( Exception exc ) { HandleError( exc ); }
|
|
|
|
return false;
|
|
}
|
|
|
|
public bool GetDoubleValue( out double val )
|
|
{
|
|
val = 0;
|
|
|
|
try
|
|
{
|
|
if ( null != m_Text && "" != m_Text )
|
|
{
|
|
val = double.Parse( m_Text );
|
|
return true;
|
|
}
|
|
}
|
|
catch ( Exception exc ) { HandleError( exc ); }
|
|
|
|
return false;
|
|
}
|
|
|
|
public bool GetIntValue( out int val )
|
|
{
|
|
val = 0;
|
|
|
|
try
|
|
{
|
|
if ( null != m_Text && "" != m_Text )
|
|
{
|
|
val = Int32.Parse( m_Text );
|
|
return true;
|
|
}
|
|
}
|
|
catch ( Exception exc ) { HandleError( exc ); }
|
|
|
|
return false;
|
|
}
|
|
|
|
public bool GetAccessLevelValue( out AccessLevel val )
|
|
{
|
|
val = AccessLevel.Player;
|
|
try
|
|
{
|
|
val = (AccessLevel)AccessLevel.Parse( typeof(Server.AccessLevel), m_Text, true );
|
|
}
|
|
catch ( Exception exc ) { HandleError( exc ); }
|
|
|
|
return true;
|
|
}
|
|
|
|
public bool GetMapValue( out Map val )
|
|
{
|
|
val = null;
|
|
try
|
|
{
|
|
val = Map.Parse( m_Text );
|
|
|
|
if ( null == val )
|
|
throw new ArgumentException( "Map expected" );
|
|
}
|
|
catch ( Exception exc ) { HandleError( exc ); }
|
|
|
|
return true;
|
|
}
|
|
|
|
public bool GetTypeValue( out Type val )
|
|
{
|
|
val = null;
|
|
try
|
|
{
|
|
val = Type.GetType( m_Text );
|
|
|
|
if ( null == val )
|
|
throw new ArgumentException( "Type expected" );
|
|
}
|
|
catch ( Exception exc ) { HandleError( exc ); }
|
|
|
|
return true;
|
|
}
|
|
|
|
public bool GetPoint3DValue( out Point3D val )
|
|
{
|
|
val = new Point3D();
|
|
int elementsExpected = 3;
|
|
|
|
try
|
|
{
|
|
if ( null == ChildElements )
|
|
return false;
|
|
|
|
if ( elementsExpected != ChildElements.Count )
|
|
throw new System.IndexOutOfRangeException( elementsExpected + " elements were expected" );
|
|
|
|
int temp;
|
|
|
|
if ( ChildElements[ 0 ].GetIntValue( out temp ))
|
|
val.X = temp;
|
|
else
|
|
throw new System.ArrayTypeMismatchException( "Int expected" );
|
|
|
|
if ( ChildElements[ 1 ].GetIntValue( out temp ))
|
|
val.Y = temp;
|
|
else
|
|
throw new System.ArrayTypeMismatchException( "Int expected" );
|
|
|
|
if ( ChildElements[ 2 ].GetIntValue( out temp ))
|
|
val.Z = temp;
|
|
else
|
|
throw new System.ArrayTypeMismatchException( "Int expected" );
|
|
}
|
|
catch ( Exception exc ) { HandleError( exc ); }
|
|
|
|
return true;
|
|
}
|
|
|
|
|
|
public bool GetArray( out bool[] val )
|
|
{
|
|
return GetArray( 0, out val );
|
|
}
|
|
|
|
public bool GetArray( int elementsExpected, out bool[] val )
|
|
{
|
|
val = null;
|
|
|
|
if ( null == ChildElements )
|
|
return false;
|
|
|
|
try
|
|
{
|
|
if ( elementsExpected > 0 && elementsExpected != ChildElements.Count )
|
|
throw new System.IndexOutOfRangeException( elementsExpected + " elements were expected" );
|
|
|
|
bool[] array = new bool[ ChildElements.Count ];
|
|
bool temp;
|
|
|
|
for ( int i = 0; i < ChildElements.Count; i++ )
|
|
{
|
|
if ( ChildElements[ i ].GetBoolValue( out temp ))
|
|
array[ i ] = temp;
|
|
else
|
|
throw new System.ArrayTypeMismatchException( "Bool expected" );
|
|
}
|
|
val = array;
|
|
}
|
|
catch ( Exception exc ) { HandleError( exc ); }
|
|
|
|
return true;
|
|
}
|
|
|
|
public bool GetArray( out int[] val )
|
|
{
|
|
return GetArray( 0, out val );
|
|
}
|
|
|
|
public bool GetArray( int elementsExpected, out int[] val )
|
|
{
|
|
val = null;
|
|
|
|
if ( null == ChildElements )
|
|
return false;
|
|
|
|
try
|
|
{
|
|
if ( elementsExpected > 0 && elementsExpected != ChildElements.Count )
|
|
throw new System.IndexOutOfRangeException( elementsExpected + " elements were expected" );
|
|
|
|
int[] array = new int[ ChildElements.Count ];
|
|
int temp;
|
|
|
|
for ( int i = 0; i < ChildElements.Count; i++ )
|
|
{
|
|
if ( ChildElements[ i ].GetIntValue( out temp ))
|
|
array[ i ] = temp;
|
|
else
|
|
throw new System.ArrayTypeMismatchException( "Int expected" );
|
|
}
|
|
val = array;
|
|
}
|
|
catch ( Exception exc ) { HandleError( exc ); }
|
|
|
|
return true;
|
|
}
|
|
|
|
public bool GetArray( out Type[] val )
|
|
{
|
|
return GetArray( 0, out val );
|
|
}
|
|
|
|
public bool GetArray( int elementsExpected, out Type[] val )
|
|
{
|
|
val = null;
|
|
|
|
if ( null == ChildElements )
|
|
return false;
|
|
|
|
try
|
|
{
|
|
if ( elementsExpected > 0 && elementsExpected != ChildElements.Count )
|
|
throw new System.IndexOutOfRangeException( elementsExpected + " elements were expected" );
|
|
|
|
Type[] array = new Type[ ChildElements.Count ];
|
|
|
|
for ( int i = 0; i < ChildElements.Count; i++ )
|
|
{
|
|
array[ i ] = Type.GetType( ChildElements[ i ].Text );
|
|
}
|
|
val = array;
|
|
}
|
|
catch ( Exception exc ) { HandleError( exc ); }
|
|
|
|
return true;
|
|
}
|
|
|
|
public bool GetArray( out string[] val )
|
|
{
|
|
return GetArray( 0, out val );
|
|
}
|
|
|
|
public bool GetArray( int elementsExpected, out string[] val )
|
|
{
|
|
val = null;
|
|
|
|
if ( null == ChildElements )
|
|
return false;
|
|
|
|
try
|
|
{
|
|
if ( elementsExpected > 0 && elementsExpected != ChildElements.Count )
|
|
throw new System.IndexOutOfRangeException( elementsExpected + " elements were expected" );
|
|
|
|
string[] array = new string[ ChildElements.Count ];
|
|
|
|
for ( int i = 0; i < ChildElements.Count; i++ )
|
|
{
|
|
if ( null != ChildElements[ i ].Text )
|
|
array[ i ] = ChildElements[ i ].Text;
|
|
else
|
|
throw new System.ArrayTypeMismatchException( "String expected" );
|
|
}
|
|
val = array;
|
|
}
|
|
catch ( Exception exc ) { HandleError( exc ); }
|
|
|
|
return true;
|
|
}
|
|
|
|
#endregion
|
|
|
|
private void HandleError( Exception exc )
|
|
{
|
|
Console.WriteLine( "\nXanthos.Utilities.ConfigParser error:\n{0}\nElement: <{1}>{2}</{1}>\n", exc.Message, TagName, Text );
|
|
#if HALT_ON_ERRORS
|
|
throw exc;
|
|
#endif
|
|
}
|
|
}
|
|
}
|