Added a SkipString() method to the parser helper; began work in implementing a configuration file parser
git-svn-id: file:///srv/devel/repo-conversion/nusu@296 d2e56fa2-650e-0410-a79f-9358c0239efd
This commit is contained in:
parent
2210973528
commit
c90033caad
39
Source/Configuration/ConfigurationFile.cs
Normal file
39
Source/Configuration/ConfigurationFile.cs
Normal file
|
@ -0,0 +1,39 @@
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.IO;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
|
||||||
|
namespace Nuclex.Support.Configuration {
|
||||||
|
|
||||||
|
/// <summary>Represents an ini- or cfg-like configuration file</summary>
|
||||||
|
/// <remarks>
|
||||||
|
/// This class tries its best to preserve the formatting of configuration files.
|
||||||
|
/// Changing a value will keep the line it appears in intact.
|
||||||
|
/// </remarks>
|
||||||
|
public class ConfigurationFile {
|
||||||
|
|
||||||
|
/// <summary>Initializes a new, empty configuration file</summary>
|
||||||
|
public ConfigurationFile() {
|
||||||
|
this.lines = new List<string>();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>Parses a configuration file from the specified text reader</summary>
|
||||||
|
/// <param name="reader">Reader the configuration file will be parsed from</param>
|
||||||
|
/// <returns>The configuration file parsed from the specified reader</returns>
|
||||||
|
public static ConfigurationFile Parse(TextReader reader) {
|
||||||
|
throw new NotImplementedException();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>Saves the configuration file into the specified writer</summary>
|
||||||
|
/// <param name="writer">Writer the configuration file will be saved into</param>
|
||||||
|
public void Save(TextWriter writer) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>Lines contained in the configuration file</summary>
|
||||||
|
private IList<string> lines;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace Nuclex.Support.Configuration
|
26
Source/Configuration/ISettings.cs
Normal file
26
Source/Configuration/ISettings.cs
Normal file
|
@ -0,0 +1,26 @@
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
|
||||||
|
namespace Nuclex.Support.Configuration {
|
||||||
|
|
||||||
|
/// <summary>Interface by which settings stored in a file can be accessed</summary>
|
||||||
|
public interface ISettings {
|
||||||
|
|
||||||
|
/// <summary>Enumerates the categories defined in the configuration</summary>
|
||||||
|
/// <returns>An enumerable list of all used categories</returns>
|
||||||
|
IEnumerable<string> EnumerateCategories();
|
||||||
|
|
||||||
|
/// <summary>Enumerates the options stored under the specified category</summary>
|
||||||
|
/// <param name="category">Category whose options will be enumerated</param>
|
||||||
|
/// <returns>An enumerable list of all options in the category</returns>
|
||||||
|
IEnumerable<OptionInfo> EnumerateOptions(string category = null);
|
||||||
|
|
||||||
|
TValue Get<TValue>(string category, string optionName);
|
||||||
|
|
||||||
|
TValue Get<TValue>(string optionName);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace Nuclex.Support.Configuration
|
15
Source/Configuration/OptionInfo.cs
Normal file
15
Source/Configuration/OptionInfo.cs
Normal file
|
@ -0,0 +1,15 @@
|
||||||
|
using System;
|
||||||
|
|
||||||
|
namespace Nuclex.Support.Configuration {
|
||||||
|
|
||||||
|
/// <summary>Informations about an option stored in a settings container</summary>
|
||||||
|
public struct OptionInfo {
|
||||||
|
|
||||||
|
/// <summary>Name of the option</summary>
|
||||||
|
public string Name;
|
||||||
|
/// <summary>Data type of the option</summary>
|
||||||
|
public Type OptionType;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace Nuclex.Support.Configuration
|
|
@ -158,6 +158,74 @@ namespace Nuclex.Support.Parsing {
|
||||||
Assert.AreEqual(5, index);
|
Assert.AreEqual(5, index);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Verifies that trying to skip text as if it was an integer skips nothing
|
||||||
|
/// </summary>
|
||||||
|
[Test]
|
||||||
|
public void SkippingTextAsIntegerReturnsFalse() {
|
||||||
|
int index = 0;
|
||||||
|
Assert.IsFalse(ParserHelper.SkipInteger("hello", ref index));
|
||||||
|
Assert.AreEqual(0, index);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>Ensures that the SkipIntegers() method can handle null strings</summary>
|
||||||
|
[Test]
|
||||||
|
public void CanSkipStringInNullString() {
|
||||||
|
int index = 0;
|
||||||
|
Assert.IsFalse(ParserHelper.SkipString((string)null, ref index));
|
||||||
|
Assert.AreEqual(0, index);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>Ensures that the SkipNumbers() method can handle empty strings</summary>
|
||||||
|
[Test]
|
||||||
|
public void CanSkipStringInEmptyString() {
|
||||||
|
int index = 0;
|
||||||
|
Assert.IsFalse(ParserHelper.SkipString(string.Empty, ref index));
|
||||||
|
Assert.AreEqual(0, index);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>Verifies that a string consisting of a single word can be skipped</summary>
|
||||||
|
[Test]
|
||||||
|
public void SingleWordStringsCanBeSkipped() {
|
||||||
|
int index = 0;
|
||||||
|
Assert.IsTrue(ParserHelper.SkipString("hello", ref index));
|
||||||
|
Assert.AreEqual(5, index);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Verifies that a space character is not skipped over when skipping a string
|
||||||
|
/// </summary>
|
||||||
|
[Test]
|
||||||
|
public void SpaceTerminatesUnquotedStrings() {
|
||||||
|
int index = 0;
|
||||||
|
Assert.IsTrue(ParserHelper.SkipString("hello world", ref index));
|
||||||
|
Assert.AreEqual(5, index);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>Verifies that a string in quotes continues until the closing quote</summary>
|
||||||
|
[Test]
|
||||||
|
public void QuotedStringsCanBeSkipped() {
|
||||||
|
int index = 0;
|
||||||
|
Assert.IsTrue(ParserHelper.SkipString("\"This is a test\"", ref index));
|
||||||
|
Assert.AreEqual(16, index);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>Verifies that a string in quotes continues until the closing quote</summary>
|
||||||
|
[Test]
|
||||||
|
public void QuotedStringsStopAtClosingQuote() {
|
||||||
|
int index = 0;
|
||||||
|
Assert.IsTrue(ParserHelper.SkipString("\"This is a test\" but this not.", ref index));
|
||||||
|
Assert.AreEqual(16, index);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>Verifies that a string in quotes continues until the closing quote</summary>
|
||||||
|
[Test]
|
||||||
|
public void QuotedStringRequiresClosingQuote() {
|
||||||
|
int index = 0;
|
||||||
|
Assert.IsFalse(ParserHelper.SkipString("\"This is missing the closing quote", ref index));
|
||||||
|
Assert.AreEqual(0, index);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace Nuclex.Support.Parsing
|
} // namespace Nuclex.Support.Parsing
|
||||||
|
|
|
@ -64,6 +64,10 @@ namespace Nuclex.Support.Parsing {
|
||||||
/// <summary>Advances the index to the next character that isn't numeric</summary>
|
/// <summary>Advances the index to the next character that isn't numeric</summary>
|
||||||
/// <param name="text">String which is being indexed</param>
|
/// <param name="text">String which is being indexed</param>
|
||||||
/// <param name="index">Index that will be advanced</param>
|
/// <param name="index">Index that will be advanced</param>
|
||||||
|
/// <remarks>
|
||||||
|
/// This skips only numeric characters, but not complete numbers -- if the number
|
||||||
|
/// begins with a minus or plus sign, for example, this function will not skip it.
|
||||||
|
/// </remarks>
|
||||||
public static void SkipNumbers(string text, ref int index) {
|
public static void SkipNumbers(string text, ref int index) {
|
||||||
if(text == null) {
|
if(text == null) {
|
||||||
return;
|
return;
|
||||||
|
@ -115,6 +119,41 @@ namespace Nuclex.Support.Parsing {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>Skips a string appearing in the input text</summary>
|
||||||
|
/// <param name="text">Text in which a string will be skipped</param>
|
||||||
|
/// <param name="index">Index at which the string begins</param>
|
||||||
|
/// <returns>True if a string was found and skipped, otherwise false</returns>
|
||||||
|
public static bool SkipString(string text, ref int index) {
|
||||||
|
if(text == null) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
int length = text.Length;
|
||||||
|
if(index >= length) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// If the string begins with an opening quote, look for the closing quote
|
||||||
|
if(text[index] == '"') {
|
||||||
|
|
||||||
|
int endIndex = text.IndexOf('"', index + 1);
|
||||||
|
if(endIndex == -1) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
index = endIndex + 1;
|
||||||
|
return true;
|
||||||
|
|
||||||
|
} else { // Normal strings end with the first whitespace
|
||||||
|
|
||||||
|
int startIndex = index;
|
||||||
|
SkipNonSpaces(text, ref index);
|
||||||
|
|
||||||
|
return (index != startIndex);
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace Nuclex.Support.Parsing
|
} // namespace Nuclex.Support.Parsing
|
||||||
|
|
Loading…
Reference in New Issue
Block a user