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:
Markus Ewald 2014-07-19 09:08:35 +00:00
parent 2210973528
commit c90033caad
5 changed files with 187 additions and 0 deletions

View 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

View 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

View 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

View File

@ -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

View File

@ -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