The configuration file store now understands 'yes' and 'no' as booleans; implemented the Get() and TryGet() methods of the windows registry settings store

git-svn-id: file:///srv/devel/repo-conversion/nusu@317 d2e56fa2-650e-0410-a79f-9358c0239efd
This commit is contained in:
Markus Ewald 2014-07-22 11:10:14 +00:00
parent e5f8b99519
commit 88105794a9
3 changed files with 78 additions and 7 deletions

View File

@ -401,6 +401,27 @@ namespace Nuclex.Support.Settings {
Assert.That(() => load(fileContents), Throws.Exception); Assert.That(() => load(fileContents), Throws.Exception);
} }
/// <summary>
/// Verifies that configuration files containing duplicate option names can not
/// be used with the configuration file store
/// </summary>
[
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<bool>(null, "value"), Is.True);
} else {
Assert.That(configurationFile.Get<bool>(null, "value"), Is.False);
}
}
/// <summary>Loads a configuration file from a string</summary> /// <summary>Loads a configuration file from a string</summary>
/// <param name="fileContents">Contents of the configuration file</param> /// <param name="fileContents">Contents of the configuration file</param>
/// <returns>The configuration file loaded from the string</returns> /// <returns>The configuration file loaded from the string</returns>

View File

@ -24,6 +24,8 @@ using System.Globalization;
using System.IO; using System.IO;
using System.Text; using System.Text;
using Nuclex.Support.Parsing;
namespace Nuclex.Support.Settings { namespace Nuclex.Support.Settings {
/// <summary>Represents an ini- or cfg-like configuration file</summary> /// <summary>Represents an ini- or cfg-like configuration file</summary>
@ -153,10 +155,22 @@ namespace Nuclex.Support.Settings {
if(containingCategory != null) { if(containingCategory != null) {
Option option; Option option;
if(containingCategory.OptionLookup.TryGetValue(optionName, out option)) { if(containingCategory.OptionLookup.TryGetValue(optionName, out option)) {
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)); value = (TValue)Convert.ChangeType(option.OptionValue.ToString(), typeof(TValue));
return true; return true;
} }
} }
}
value = default(TValue); value = default(TValue);
return false; return false;

View File

@ -22,8 +22,10 @@ License along with this library
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Globalization;
using Microsoft.Win32; using Microsoft.Win32;
using Nuclex.Support.Parsing; using Nuclex.Support.Parsing;
namespace Nuclex.Support.Settings { namespace Nuclex.Support.Settings {
@ -126,14 +128,11 @@ namespace Nuclex.Support.Settings {
/// parameter, false otherwise /// parameter, false otherwise
/// </returns> /// </returns>
public bool TryGet<TValue>(string category, string optionName, out TValue value) { public bool TryGet<TValue>(string category, string optionName, out TValue value) {
throw new NotImplementedException();
if(string.IsNullOrEmpty(category)) { if(string.IsNullOrEmpty(category)) {
object valueAsObject = this.rootKey.GetValue(optionName); return tryGetValueFromKey(this.rootKey, optionName, out value);
value = (TValue)Convert.ChangeType(valueAsObject, typeof(TValue));
} else { } else {
using(RegistryKey categoryKey = this.rootKey.OpenSubKey(category, this.writable)) { using(RegistryKey categoryKey = this.rootKey.OpenSubKey(category, this.writable)) {
object valueAsObject = this.rootKey.GetValue(optionName); return tryGetValueFromKey(this.rootKey, optionName, out value);
value = (TValue)Convert.ChangeType(valueAsObject, typeof(TValue));
} }
} }
} }
@ -155,6 +154,43 @@ namespace Nuclex.Support.Settings {
throw new NotImplementedException(); throw new NotImplementedException();
} }
/// <summary>Tries to retrieve the value of a registry key if it exists</summary>
/// <typeparam name="TValue">Type of value the registry key is expected to have</typeparam>
/// <param name="categoryKey">Registry key the value is stored under</param>
/// <param name="optionName">Name of the option in the registry</param>
/// <param name="value">Will receive the value read from the registry</param>
/// <returns>True if the value was found, false otherwise</returns>
private bool tryGetValueFromKey<TValue>(
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;
}
}
/// <summary>Figures out which .NET type best matches the registry value</summary> /// <summary>Figures out which .NET type best matches the registry value</summary>
/// <param name="categoryKey">Registry key the key is stored in</param> /// <param name="categoryKey">Registry key the key is stored in</param>
/// <param name="optionName">Name of the option that will be retrieved</param> /// <param name="optionName">Name of the option that will be retrieved</param>