From c90033caadfdc7c3c4c9ff9dc63c2ee9c78de985 Mon Sep 17 00:00:00 2001 From: Markus Ewald Date: Sat, 19 Jul 2014 09:08:35 +0000 Subject: [PATCH] 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 --- Source/Configuration/ConfigurationFile.cs | 39 +++++++++++++ Source/Configuration/ISettings.cs | 26 +++++++++ Source/Configuration/OptionInfo.cs | 15 +++++ Source/Parsing/ParserHelper.Test.cs | 68 +++++++++++++++++++++++ Source/Parsing/ParserHelper.cs | 39 +++++++++++++ 5 files changed, 187 insertions(+) create mode 100644 Source/Configuration/ConfigurationFile.cs create mode 100644 Source/Configuration/ISettings.cs create mode 100644 Source/Configuration/OptionInfo.cs diff --git a/Source/Configuration/ConfigurationFile.cs b/Source/Configuration/ConfigurationFile.cs new file mode 100644 index 0000000..f953541 --- /dev/null +++ b/Source/Configuration/ConfigurationFile.cs @@ -0,0 +1,39 @@ +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Text; + +namespace Nuclex.Support.Configuration { + + /// Represents an ini- or cfg-like configuration file + /// + /// This class tries its best to preserve the formatting of configuration files. + /// Changing a value will keep the line it appears in intact. + /// + public class ConfigurationFile { + + /// Initializes a new, empty configuration file + public ConfigurationFile() { + this.lines = new List(); + } + + /// Parses a configuration file from the specified text reader + /// Reader the configuration file will be parsed from + /// The configuration file parsed from the specified reader + public static ConfigurationFile Parse(TextReader reader) { + throw new NotImplementedException(); + } + + /// Saves the configuration file into the specified writer + /// Writer the configuration file will be saved into + public void Save(TextWriter writer) { + + } + + /// Lines contained in the configuration file + private IList lines; + + } + +} // namespace Nuclex.Support.Configuration diff --git a/Source/Configuration/ISettings.cs b/Source/Configuration/ISettings.cs new file mode 100644 index 0000000..a917777 --- /dev/null +++ b/Source/Configuration/ISettings.cs @@ -0,0 +1,26 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; + +namespace Nuclex.Support.Configuration { + + /// Interface by which settings stored in a file can be accessed + public interface ISettings { + + /// Enumerates the categories defined in the configuration + /// An enumerable list of all used categories + IEnumerable EnumerateCategories(); + + /// Enumerates the options stored under the specified category + /// Category whose options will be enumerated + /// An enumerable list of all options in the category + IEnumerable EnumerateOptions(string category = null); + + TValue Get(string category, string optionName); + + TValue Get(string optionName); + + } + +} // namespace Nuclex.Support.Configuration diff --git a/Source/Configuration/OptionInfo.cs b/Source/Configuration/OptionInfo.cs new file mode 100644 index 0000000..4671963 --- /dev/null +++ b/Source/Configuration/OptionInfo.cs @@ -0,0 +1,15 @@ +using System; + +namespace Nuclex.Support.Configuration { + + /// Informations about an option stored in a settings container + public struct OptionInfo { + + /// Name of the option + public string Name; + /// Data type of the option + public Type OptionType; + + } + +} // namespace Nuclex.Support.Configuration diff --git a/Source/Parsing/ParserHelper.Test.cs b/Source/Parsing/ParserHelper.Test.cs index b929a26..51a7bd2 100644 --- a/Source/Parsing/ParserHelper.Test.cs +++ b/Source/Parsing/ParserHelper.Test.cs @@ -158,6 +158,74 @@ namespace Nuclex.Support.Parsing { Assert.AreEqual(5, index); } + /// + /// Verifies that trying to skip text as if it was an integer skips nothing + /// + [Test] + public void SkippingTextAsIntegerReturnsFalse() { + int index = 0; + Assert.IsFalse(ParserHelper.SkipInteger("hello", ref index)); + Assert.AreEqual(0, index); + } + + /// Ensures that the SkipIntegers() method can handle null strings + [Test] + public void CanSkipStringInNullString() { + int index = 0; + Assert.IsFalse(ParserHelper.SkipString((string)null, ref index)); + Assert.AreEqual(0, index); + } + + /// Ensures that the SkipNumbers() method can handle empty strings + [Test] + public void CanSkipStringInEmptyString() { + int index = 0; + Assert.IsFalse(ParserHelper.SkipString(string.Empty, ref index)); + Assert.AreEqual(0, index); + } + + /// Verifies that a string consisting of a single word can be skipped + [Test] + public void SingleWordStringsCanBeSkipped() { + int index = 0; + Assert.IsTrue(ParserHelper.SkipString("hello", ref index)); + Assert.AreEqual(5, index); + } + + /// + /// Verifies that a space character is not skipped over when skipping a string + /// + [Test] + public void SpaceTerminatesUnquotedStrings() { + int index = 0; + Assert.IsTrue(ParserHelper.SkipString("hello world", ref index)); + Assert.AreEqual(5, index); + } + + /// Verifies that a string in quotes continues until the closing quote + [Test] + public void QuotedStringsCanBeSkipped() { + int index = 0; + Assert.IsTrue(ParserHelper.SkipString("\"This is a test\"", ref index)); + Assert.AreEqual(16, index); + } + + /// Verifies that a string in quotes continues until the closing quote + [Test] + public void QuotedStringsStopAtClosingQuote() { + int index = 0; + Assert.IsTrue(ParserHelper.SkipString("\"This is a test\" but this not.", ref index)); + Assert.AreEqual(16, index); + } + + /// Verifies that a string in quotes continues until the closing quote + [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 diff --git a/Source/Parsing/ParserHelper.cs b/Source/Parsing/ParserHelper.cs index 333b4cf..81c7301 100644 --- a/Source/Parsing/ParserHelper.cs +++ b/Source/Parsing/ParserHelper.cs @@ -64,6 +64,10 @@ namespace Nuclex.Support.Parsing { /// Advances the index to the next character that isn't numeric /// String which is being indexed /// Index that will be advanced + /// + /// 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. + /// public static void SkipNumbers(string text, ref int index) { if(text == null) { return; @@ -115,6 +119,41 @@ namespace Nuclex.Support.Parsing { return true; } + /// Skips a string appearing in the input text + /// Text in which a string will be skipped + /// Index at which the string begins + /// True if a string was found and skipped, otherwise false + 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