diff --git a/Source/Settings/ConfigurationFileStore.Test.cs b/Source/Settings/ConfigurationFileStore.Test.cs
index 5b1cb23..a096af1 100644
--- a/Source/Settings/ConfigurationFileStore.Test.cs
+++ b/Source/Settings/ConfigurationFileStore.Test.cs
@@ -401,6 +401,27 @@ namespace Nuclex.Support.Settings {
Assert.That(() => load(fileContents), Throws.Exception);
}
+ ///
+ /// Verifies that configuration files containing duplicate option names can not
+ /// be used with the configuration file store
+ ///
+ [
+ Test,
+ TestCase("value = yes", true),
+ TestCase("value = true", true),
+ TestCase("value = no", false),
+ TestCase("value = false", false)
+ ]
+ public void BooleanLiteralsAreUnderstood(string fileContents, bool expectedValue) {
+ ConfigurationFileStore configurationFile = load(fileContents);
+
+ if(expectedValue) {
+ Assert.That(configurationFile.Get(null, "value"), Is.True);
+ } else {
+ Assert.That(configurationFile.Get(null, "value"), Is.False);
+ }
+ }
+
/// Loads a configuration file from a string
/// Contents of the configuration file
/// The configuration file loaded from the string
diff --git a/Source/Settings/ConfigurationFileStore.cs b/Source/Settings/ConfigurationFileStore.cs
index cd96236..5481d1d 100644
--- a/Source/Settings/ConfigurationFileStore.cs
+++ b/Source/Settings/ConfigurationFileStore.cs
@@ -24,6 +24,8 @@ using System.Globalization;
using System.IO;
using System.Text;
+using Nuclex.Support.Parsing;
+
namespace Nuclex.Support.Settings {
/// Represents an ini- or cfg-like configuration file
@@ -153,8 +155,20 @@ namespace Nuclex.Support.Settings {
if(containingCategory != null) {
Option option;
if(containingCategory.OptionLookup.TryGetValue(optionName, out option)) {
- value = (TValue)Convert.ChangeType(option.OptionValue.ToString(), typeof(TValue));
- return true;
+ if(typeof(TValue) == typeof(bool)) {
+ bool? boolean = ParserHelper.ParseBooleanLiteral(ref option.OptionValue);
+ if(boolean.HasValue) {
+ value = (TValue)(object)boolean.Value;
+ return true;
+ } else {
+ throw new FormatException(
+ "The value '" + option.OptionValue.ToString() + "' is not a boolean"
+ );
+ }
+ } else {
+ value = (TValue)Convert.ChangeType(option.OptionValue.ToString(), typeof(TValue));
+ return true;
+ }
}
}
diff --git a/Source/Settings/WindowsRegistryStore.cs b/Source/Settings/WindowsRegistryStore.cs
index 04e0567..560fd3d 100644
--- a/Source/Settings/WindowsRegistryStore.cs
+++ b/Source/Settings/WindowsRegistryStore.cs
@@ -22,8 +22,10 @@ License along with this library
using System;
using System.Collections.Generic;
+using System.Globalization;
using Microsoft.Win32;
+
using Nuclex.Support.Parsing;
namespace Nuclex.Support.Settings {
@@ -126,14 +128,11 @@ namespace Nuclex.Support.Settings {
/// parameter, false otherwise
///
public bool TryGet(string category, string optionName, out TValue value) {
- throw new NotImplementedException();
if(string.IsNullOrEmpty(category)) {
- object valueAsObject = this.rootKey.GetValue(optionName);
- value = (TValue)Convert.ChangeType(valueAsObject, typeof(TValue));
+ return tryGetValueFromKey(this.rootKey, optionName, out value);
} else {
using(RegistryKey categoryKey = this.rootKey.OpenSubKey(category, this.writable)) {
- object valueAsObject = this.rootKey.GetValue(optionName);
- value = (TValue)Convert.ChangeType(valueAsObject, typeof(TValue));
+ return tryGetValueFromKey(this.rootKey, optionName, out value);
}
}
}
@@ -155,6 +154,43 @@ namespace Nuclex.Support.Settings {
throw new NotImplementedException();
}
+ /// Tries to retrieve the value of a registry key if it exists
+ /// Type of value the registry key is expected to have
+ /// Registry key the value is stored under
+ /// Name of the option in the registry
+ /// Will receive the value read from the registry
+ /// True if the value was found, false otherwise
+ private bool tryGetValueFromKey(
+ RegistryKey categoryKey, string optionName, out TValue value
+ ) {
+ object valueAsObject = categoryKey.GetValue(optionName);
+ if(valueAsObject == null) {
+ value = default(TValue);
+ return false;
+ }
+
+ if(typeof(TValue) == typeof(bool)) {
+ string valueAsString = (string)Convert.ChangeType(
+ valueAsObject, typeof(string), CultureInfo.InvariantCulture
+ );
+
+ bool? boolean = ParserHelper.ParseBooleanLiteral(valueAsString);
+ if(boolean.HasValue) {
+ value = (TValue)(object)boolean.Value;
+ return true;
+ } else {
+ throw new FormatException(
+ "The value '" + valueAsString + "' can not be intepreted as a boolean"
+ );
+ }
+ } else {
+ value = (TValue)Convert.ChangeType(
+ valueAsObject, typeof(TValue), CultureInfo.InvariantCulture
+ );
+ return true;
+ }
+ }
+
/// Figures out which .NET type best matches the registry value
/// Registry key the key is stored in
/// Name of the option that will be retrieved