Files
libremetaverse/ExtensionLoader/Ini/IniDocument.cs
2008-10-29 20:38:51 +00:00

303 lines
8.2 KiB
C#

#region Copyright
//
// Nini Configuration Project.
// Copyright (C) 2006 Brent R. Matzelle. All rights reserved.
//
// This software is published under the terms of the MIT X11 license, a copy of
// which has been included with this distribution in the LICENSE.txt file.
//
#endregion
using System;
using System.IO;
using System.Collections;
using ExtensionLoader.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
}
}