84 lines
2.9 KiB
C#
84 lines
2.9 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using System.Linq;
|
|
using System.Reflection;
|
|
using System.Text.RegularExpressions;
|
|
|
|
namespace Raytheon.Units
|
|
{
|
|
/// <summary>
|
|
/// Contains info related to a unit: to parse, print, and convert values
|
|
/// </summary>
|
|
internal class UnitInfo<T>
|
|
{
|
|
public UnitInfo( List<string> abbreviation,
|
|
Func<double, T> conversionMethod,
|
|
MethodInfo propertyGetter )
|
|
{
|
|
Abbreviation = abbreviation;
|
|
ConversionMethod = conversionMethod;
|
|
PropertyGetter = propertyGetter;
|
|
}
|
|
|
|
/// <summary>
|
|
/// standard text abbreviation for this unit
|
|
/// </summary>
|
|
public List<string> Abbreviation { get; private set; }
|
|
|
|
/// <summary>
|
|
/// method for converting string to this unit
|
|
/// </summary>
|
|
public Func<double, T> ConversionMethod { get; private set; }
|
|
|
|
/// <summary>
|
|
/// get method for the property associated with this unit
|
|
/// </summary>
|
|
public MethodInfo PropertyGetter { get; set; }
|
|
}
|
|
|
|
internal class Common
|
|
{
|
|
/// <summary>
|
|
/// Converts a string that represents a number with a unit to the actual
|
|
/// unit type.
|
|
/// </summary>
|
|
/// <typeparam name="E">Enumeration of the Unit abbreviation</typeparam>
|
|
/// <typeparam name="T">The actual unit type, i.e Current</typeparam>
|
|
/// <param name="s">String that represents a unit value, i.e 1.23 Amps</param>
|
|
/// <param name="unitInfo">Look up table for how to convert the units</param>
|
|
/// <returns>
|
|
/// The converted number to the correct unit type. If unable to parse, will return the first
|
|
/// <see cref="UnitInfo{T}.ConversionMethod"/> with a value of <see cref="double.NaN"/>
|
|
/// </returns>
|
|
public static T Parse<E, T>( string s, IDictionary<E, UnitInfo<T>> unitInfo )
|
|
{
|
|
const string FloatingPointPattern = @"([-+]?[0-9]+(\.[0-9]+)?([Ee][+-][0-9]+)?)";
|
|
const string AbbreviationPattern = @"([\w/\^]*)";
|
|
string pattern = FloatingPointPattern + @"\s*" + AbbreviationPattern;
|
|
|
|
Regex regEx = new Regex( pattern );
|
|
Match match = regEx.Match( s );
|
|
|
|
if(!match.Success || match.Groups.Count == 0 )
|
|
{
|
|
throw new FormatException( $"UUnknown value : {s}" );
|
|
}
|
|
|
|
string abbreviation = match.Groups[match.Groups.Count - 1].Value;
|
|
|
|
IEnumerable<UnitInfo<T>> x = unitInfo.Where( kvp => kvp.Value.Abbreviation.Contains( abbreviation, StringComparer.CurrentCultureIgnoreCase ) )
|
|
.Select( kvp => kvp.Value );
|
|
|
|
// abbreviation not found?
|
|
if ( x.Count( ) == 0 )
|
|
{
|
|
throw new FormatException( $"Unknown units: '{abbreviation}'" );
|
|
}
|
|
|
|
double value = double.Parse( match.Groups[1].Value );
|
|
|
|
return x.First( ).ConversionMethod( value );
|
|
}
|
|
}
|
|
}
|