zaaReloaded2/zaaReloaded2/Thesaurus/ThesaurusBase.cs

292 lines
10 KiB
C#
Executable File

/* DictionaryBase.cs
* part of zaaReloaded2
*
* Copyright 2015-2018 Daniel Kraus
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
namespace zaaReloaded2.Thesaurus
{
/// <summary>
/// Base class for the <see cref="Parameters"/>
/// and the <see cref="Units"/>; implements methods
/// to read configuration files.
/// </summary>
public abstract class ThesaurusBase
{
#region Public properties
/// <summary>
/// Gets a sorted dictionary of records. The records are sorted by the
/// first field, and each record contains the entire set of fields,
/// including the first field.
/// </summary>
public SortedDictionary<string, string[]> Records { get; protected set; }
#endregion
#region Constructor
/// <summary>
/// Constructs a new dictionary, loading default data from a built-in
/// resource, and user data from a custom file.
/// </summary>
public ThesaurusBase()
{
Records = new SortedDictionary<string, string[]>();
LoadDefaultValues();
LoadUserValues();
}
#endregion
#region Public methods
/// <summary>
/// Returns true if the dictionary contains a record for
/// <paramref name="key"/>.
/// </summary>
/// <param name="key">Dictionary key to look up.</param>
/// <returns>True if a record for <paramref name="key"/>
/// exist, false if not.</returns>
public bool HasRecord(string key)
{
return Records.ContainsKey(key);
}
#endregion
#region Abstract methods
/// <summary>
/// Returns a content stream with a default configuration file.
/// </summary>
abstract protected Stream GetDefaultStream();
/// <summary>
/// Returns the file name of the text file that contains user-defined
/// values.
/// </summary>
/// <returns>File name.</returns>
abstract protected string GetUserFileName();
#endregion
#region Protected methods
/// <summary>
/// Reads a text file from a TextReader and fills the dictionary
/// with the data.
/// </summary>
/// <param name="s">TextReader that provides a text file.</param>
protected void ReadFile(TextReader text)
{
LineParser lp = new LineParser();
string line;
string key;
while ((line = text.ReadLine()) != null)
{
lp.Line = line;
if (lp.HasFields)
{
key = lp.Fields[0];
if (Records.ContainsKey(key))
{
Records[key] = lp.Fields;
}
else
{
Records.Add(key, lp.Fields);
}
}
}
}
/// <summary>
/// Reads a text file from a stream and fills the dictionary
/// with the data.
/// </summary>
/// <param name="s">TextReader that provides a text file.</param>
protected void ReadFile(Stream stream)
{
StreamReader sr = new StreamReader(stream);
ReadFile(sr);
}
/// <summary>
/// Loads default dictionary values from a text file that is built
/// into the assembly as an embbedded resource.
/// </summary>
protected virtual void LoadDefaultValues()
{
ReadFile(GetDefaultStream());
}
/// <summary>
/// Attempts to load additional values from a user file whose path
/// is provided by <see cref="GetUserFileName()"/>.
/// </summary>
protected virtual void LoadUserValues()
{
try
{
FileStream fs = new FileStream(GetUserFileName(), FileMode.Open, FileAccess.Read);
ReadFile(fs);
}
catch { }
}
/// <summary>
/// Looks up a dictionary key and returns an integer value from the requested field,
/// or a default value if the field is empty or contains only dashes.
/// </summary>
/// <param name="key">Key to look up.</param>
/// <param name="fieldNum">Zero-based index of the field to look up
/// (note that field 0 is the key itself).</param>
/// <param name="defaultValue">Default value that will be returned
/// if the field is empty or contains only dashes.</param>
/// <returns>Value of the requested field, or <paramref name="defaultValue"/>
/// if the field is empty or contains only dashes.</returns>
/// <exception cref="System.IndexOutOfRangeException">if fieldNum is negative.</exception>
protected int LookUpValue(string key, int fieldNum, int defaultValue)
{
string[] record;
if (Records.TryGetValue(key, out record))
{
if (fieldNum >= record.Length) return defaultValue;
string value = record[fieldNum];
if (string.IsNullOrWhiteSpace(value) || _dashes.IsMatch(value))
{
return defaultValue;
}
else
{
int intval;
if (int.TryParse(value, out intval))
{
return intval;
}
else
{
return defaultValue;
}
}
}
else
{
return defaultValue;
}
}
/// <summary>
/// Looks up a dictionary key and returns the value from the requested field,
/// or a default value if the field is empty or contains only dashes.
/// </summary>
/// <param name="key">Key to look up.</param>
/// <param name="fieldNum">Zero-based index of the field to look up
/// (note that field 0 is the key itself).</param>
/// <param name="defaultValue">Default value that will be returned
/// if the field is empty or contains only dashes.</param>
/// <returns>Value of the requested field, or <paramref name="defaultValue"/>
/// if the field is empty or contains only dashes.</returns>
/// <exception cref="System.IndexOutOfRangeException">if fieldNum is negative.</exception>
protected string LookUpValue(string key, int fieldNum, string defaultValue)
{
string[] record;
if (Records.TryGetValue(key, out record))
{
if (fieldNum >= record.Length) return defaultValue;
string value = record[fieldNum];
if (string.IsNullOrWhiteSpace(value) || _dashes.IsMatch(value))
{
return defaultValue;
}
else
{
return value;
}
}
else
{
return defaultValue;
}
}
/// <summary>
/// Looks up a dictionary key and returns the value from the requested field,
/// or an empty string if the field is empty or contains only dashes.
/// </summary>
/// <param name="key">Key to look up.</param>
/// <param name="fieldNum">Zero-based index of the field to look up
/// (note that field 0 is the key itself).</param>
/// <returns>Value of the requested field, or <see cref="String.Empty"/>
/// if the field is empty or contains only dashes.</returns>
/// <exception cref="System.IndexOutOfRangeException">if fieldNum is negative.</exception>
protected string LookUpValue(string key, int fieldNum)
{
return LookUpValue(key, fieldNum, String.Empty);
}
/// <summary>
/// Looks up a dictionary key and returns a boolean value from the requested field,
/// or a default value if the field is empty or contains only dashes.
/// </summary>
/// <remarks>
/// The following case-insensitive text values are evaluated as "true": X, Y, J, +,
/// 1, JA, TRUE, WAHR.
/// </remarks>
/// <param name="key">Key to look up.</param>
/// <param name="fieldNum">Zero-based index of the field to look up
/// (note that field 0 is the key itself).</param>
/// <param name="defaultValue">Default value that will be returned
/// if the field is empty or contains only dashes.</param>
/// <returns>Value of the requested field, or <paramref name="defaultValue"/>
/// if the field is empty or contains only dashes.</returns>
/// <exception cref="System.IndexOutOfRangeException">if fieldNum is negative.</exception>
protected bool LookUpValue(string key, int fieldNum, bool defaultValue)
{
string textValue = LookUpValue(key, fieldNum, String.Empty);
switch (textValue.ToUpper())
{
case "X":
case "Y":
case "J":
case "+":
case "1":
case "JA":
case "YES":
case "TRUE":
case "WAHR":
return true;
default:
return defaultValue;
}
}
#endregion
#region Fields
private static readonly Regex _dashes = new Regex("^-+$");
#endregion
}
}