diff --git a/SabreTools.Core/Tools/NumberHelper.cs b/SabreTools.Core/Tools/NumberHelper.cs index 2c43b103..8a5b0d3d 100644 --- a/SabreTools.Core/Tools/NumberHelper.cs +++ b/SabreTools.Core/Tools/NumberHelper.cs @@ -1,4 +1,5 @@ using System; +using System.Linq; namespace SabreTools.Core.Tools { @@ -81,8 +82,11 @@ namespace SabreTools.Core.Tools /// /// Determine the multiplier from a numeric string /// - private static long DetermineMultiplier(string numeric) + public static long DetermineMultiplier(string? numeric) { + if (string.IsNullOrWhiteSpace(numeric)) + return 0; + long multiplier = 1; if (numeric.EndsWith("k") || numeric.EndsWith("kb")) multiplier = KiloByte; @@ -119,5 +123,67 @@ namespace SabreTools.Core.Tools return multiplier; } + + /// + /// Determine if a string is fully numeric or not + /// + public static bool IsNumeric(string? value) + { + // If we have no value, it is not numeric + if (string.IsNullOrWhiteSpace(value)) + return false; + + // If we have a hex value + value = value.ToLowerInvariant(); + if (value.StartsWith("0x")) + value = value[2..]; + + if (DetermineMultiplier(value) > 1) + value = value.TrimEnd(new char[] { 'k', 'm', 'g', 't', 'p', 'e', 'z', 'y', 'i', 'b', ' ' }); + +#if NET7_0_OR_GREATER + return value.All(c => char.IsAsciiHexDigit(c) || c == '.' || c == ','); +#else + return value.All(c => c.IsAsciiHexDigit()|| c == '.' || c == ','); +#endif + } + +#if NET6_0 + /// + /// Indicates whether a character is categorized as an ASCII hexademical digit. + /// + /// The character to evaluate. + /// true if c is a hexademical digit; otherwise, false. + /// This method determines whether the character is in the range '0' through '9', inclusive, 'A' through 'F', inclusive, or 'a' through 'f', inclusive. + private static bool IsAsciiHexDigit(this char c) + { + return c switch + { + '0' => true, + '1' => true, + '2' => true, + '3' => true, + '4' => true, + '5' => true, + '6' => true, + '7' => true, + '8' => true, + '9' => true, + 'a' => true, + 'A' => true, + 'b' => true, + 'B' => true, + 'c' => true, + 'C' => true, + 'd' => true, + 'D' => true, + 'e' => true, + 'E' => true, + 'f' => true, + 'F' => true, + _ => false, + }; + } +#endif } } \ No newline at end of file diff --git a/SabreTools.Filter/FilterObject.cs b/SabreTools.Filter/FilterObject.cs index 0fc8b62b..696dfc79 100644 --- a/SabreTools.Filter/FilterObject.cs +++ b/SabreTools.Filter/FilterObject.cs @@ -1,5 +1,7 @@ using System; +using System.Linq; using System.Text.RegularExpressions; +using SabreTools.Core.Tools; using SabreTools.Models.Internal; namespace SabreTools.Filter @@ -86,7 +88,6 @@ namespace SabreTools.Filter /// /// /// TODO: Add regex matching to this method - /// TODO: Add logic to convert SI suffixes and hex /// private bool MatchesEqual(DictionaryBase dictionaryBase) { @@ -94,6 +95,19 @@ namespace SabreTools.Filter return this.Value == null; string? checkValue = dictionaryBase.ReadString(this.Key[1]); + if (NumberHelper.IsNumeric(checkValue) && NumberHelper.IsNumeric(this.Value)) + { + long? checkValueLong = NumberHelper.ConvertToInt64(checkValue); + long? matchValueLong = NumberHelper.ConvertToInt64(checkValue); + if (checkValueLong != null && matchValueLong != null) + return checkValueLong == matchValueLong; + + double? checkValueDouble = NumberHelper.ConvertToDouble(checkValue); + double? matchValueDouble = NumberHelper.ConvertToDouble(checkValue); + if (checkValueDouble != null && matchValueDouble != null) + return checkValueDouble == matchValueDouble; + } + return checkValue == this.Value; } @@ -102,7 +116,6 @@ namespace SabreTools.Filter /// /// /// TODO: Add regex matching to this method - /// TODO: Add logic to convert SI suffixes and hex /// private bool MatchesNotEqual(DictionaryBase dictionaryBase) { @@ -110,13 +123,25 @@ namespace SabreTools.Filter return this.Value != null; string? checkValue = dictionaryBase.ReadString(this.Key[1]); + if (NumberHelper.IsNumeric(checkValue) && NumberHelper.IsNumeric(this.Value)) + { + long? checkValueLong = NumberHelper.ConvertToInt64(checkValue); + long? matchValueLong = NumberHelper.ConvertToInt64(checkValue); + if (checkValueLong != null && matchValueLong != null) + return checkValueLong != matchValueLong; + + double? checkValueDouble = NumberHelper.ConvertToDouble(checkValue); + double? matchValueDouble = NumberHelper.ConvertToDouble(checkValue); + if (checkValueDouble != null && matchValueDouble != null) + return checkValueDouble != matchValueDouble; + } + return checkValue != this.Value; } /// /// Determines if a value is strictly greater than /// - /// TODO: Add logic to convert SI suffixes and hex private bool MatchesGreaterThan(DictionaryBase dictionaryBase) { if (!dictionaryBase.ContainsKey(this.Key[1])) @@ -125,7 +150,8 @@ namespace SabreTools.Filter long? checkLongValue = dictionaryBase.ReadLong(this.Key[1]); if (checkLongValue != null) { - if (!long.TryParse(this.Value, out long matchValue)) + long? matchValue = NumberHelper.ConvertToInt64(this.Value); + if (matchValue == null) return false; return checkLongValue > matchValue; @@ -134,7 +160,8 @@ namespace SabreTools.Filter double? checkDoubleValue = dictionaryBase.ReadDouble(this.Key[1]); if (checkDoubleValue != null) { - if (!double.TryParse(this.Value, out double matchValue)) + double? matchValue = NumberHelper.ConvertToDouble(this.Value); + if (matchValue == null) return false; return checkDoubleValue > matchValue; @@ -146,7 +173,6 @@ namespace SabreTools.Filter /// /// Determines if a value is greater than or equal /// - /// TODO: Add logic to convert SI suffixes and hex private bool MatchesGreaterThanOrEqual(DictionaryBase dictionaryBase) { if (!dictionaryBase.ContainsKey(this.Key[1])) @@ -155,7 +181,8 @@ namespace SabreTools.Filter long? checkLongValue = dictionaryBase.ReadLong(this.Key[1]); if (checkLongValue != null) { - if (!long.TryParse(this.Value, out long matchValue)) + long? matchValue = NumberHelper.ConvertToInt64(this.Value); + if (matchValue == null) return false; return checkLongValue >= matchValue; @@ -164,7 +191,8 @@ namespace SabreTools.Filter double? checkDoubleValue = dictionaryBase.ReadDouble(this.Key[1]); if (checkDoubleValue != null) { - if (!double.TryParse(this.Value, out double matchValue)) + double? matchValue = NumberHelper.ConvertToDouble(this.Value); + if (matchValue == null) return false; return checkDoubleValue >= matchValue; @@ -176,7 +204,6 @@ namespace SabreTools.Filter /// /// Determines if a value is strictly less than /// - /// TODO: Add logic to convert SI suffixes and hex private bool MatchesLessThan(DictionaryBase dictionaryBase) { if (!dictionaryBase.ContainsKey(this.Key[1])) @@ -185,7 +212,8 @@ namespace SabreTools.Filter long? checkLongValue = dictionaryBase.ReadLong(this.Key[1]); if (checkLongValue != null) { - if (!long.TryParse(this.Value, out long matchValue)) + long? matchValue = NumberHelper.ConvertToInt64(this.Value); + if (matchValue == null) return false; return checkLongValue < matchValue; @@ -194,7 +222,8 @@ namespace SabreTools.Filter double? checkDoubleValue = dictionaryBase.ReadDouble(this.Key[1]); if (checkDoubleValue != null) { - if (!double.TryParse(this.Value, out double matchValue)) + double? matchValue = NumberHelper.ConvertToDouble(this.Value); + if (matchValue == null) return false; return checkDoubleValue < matchValue; @@ -206,7 +235,6 @@ namespace SabreTools.Filter /// /// Determines if a value is less than or equal /// - /// TODO: Add logic to convert SI suffixes and hex private bool MatchesLessThanOrEqual(DictionaryBase dictionaryBase) { if (!dictionaryBase.ContainsKey(this.Key[1])) @@ -215,7 +243,8 @@ namespace SabreTools.Filter long? checkLongValue = dictionaryBase.ReadLong(this.Key[1]); if (checkLongValue != null) { - if (!long.TryParse(this.Value, out long matchValue)) + long? matchValue = NumberHelper.ConvertToInt64(this.Value); + if (matchValue == null) return false; return checkLongValue <= matchValue; @@ -224,7 +253,8 @@ namespace SabreTools.Filter double? checkDoubleValue = dictionaryBase.ReadDouble(this.Key[1]); if (checkDoubleValue != null) { - if (!double.TryParse(this.Value, out double matchValue)) + double? matchValue = NumberHelper.ConvertToDouble(this.Value); + if (matchValue == null) return false; return checkDoubleValue <= matchValue; diff --git a/SabreTools.Filter/SabreTools.Filter.csproj b/SabreTools.Filter/SabreTools.Filter.csproj index abcdc453..a2a55b9d 100644 --- a/SabreTools.Filter/SabreTools.Filter.csproj +++ b/SabreTools.Filter/SabreTools.Filter.csproj @@ -6,6 +6,7 @@ +