/// <summary> /// Checks whether a new unit abbreviation can be defined (or may be redefined) in this context. /// </summary> /// <param name="a">The proposed abbreviation.</param> /// <param name="autoStandardPrefix"> /// Whether the new unit must support automatic metric and/or binary standard prefixes. /// </param> /// <returns>The <see cref="NewAbbreviationConflict"/> flag.</returns> public NewAbbreviationConflict CheckValidNewAbbreviation(string a, AutoStandardPrefix autoStandardPrefix) { if (_allUnits.ContainsKey(a)) { return(NewAbbreviationConflict.Exists); } if (String.IsNullOrEmpty(a) || !a.All(c => Char.IsLetter(c) || Char.IsSymbol(c) || c == '#' || c == '%' || c == '‰' || c == '‱' || c == '㏙')) { return(NewAbbreviationConflict.InvalidCharacters); } foreach (var withPrefix in MeasureStandardPrefix.GetPrefixes(autoStandardPrefix) .Select(p => p.Abbreviation + a)) { if (_allUnits.ContainsKey(withPrefix)) { return(NewAbbreviationConflict.AmbiguousAutoStandardPrefix); } } // Optimization: if the new abbreviation does not start with a // standard prefix, it is useless to challenge it against // existing units. var prefix = MeasureStandardPrefix.FindPrefix(a); if (prefix != MeasureStandardPrefix.None && _allUnits.Values .OfType <AtomicMeasureUnit>() .Where(u => u.AutoStandardPrefix != AutoStandardPrefix.None) .SelectMany(u => MeasureStandardPrefix.GetPrefixes(u.AutoStandardPrefix) .Where(p => p != MeasureStandardPrefix.None) .Select(p => p.Abbreviation + u.Abbreviation)) .Any(exists => exists == a)) { return(NewAbbreviationConflict.MatchPotentialAutoStandardPrefixedUnit); } return(NewAbbreviationConflict.None); }
/// <summary> /// Checks whether a new unit abbreviation can be defined in this context. /// </summary> /// <param name="a">The proposed abbreviation.</param> /// <param name="autoStandardPrefix"> /// Whether the new unit must support automatic metric and/or binary standard prefixes. /// </param> /// <returns>True if the abbreviation can be used, false otherwise.</returns> public bool IsValidNewAbbreviation(string a, AutoStandardPrefix autoStandardPrefix) { if (String.IsNullOrEmpty(a) || !a.All(c => Char.IsLetter(c) || Char.IsSymbol(c) || c == '#' || c == '%' || c == '‰' || c == '‱' || c == '㏙')) { return(false); } foreach (var withPrefix in MeasureStandardPrefix.GetPrefixes(autoStandardPrefix) .Select(p => p.Abbreviation + a)) { if (_allUnits.ContainsKey(withPrefix)) { return(false); } } var prefix = MeasureStandardPrefix.FindPrefix(a); // Optimization: if the new abbreviation does not start with a // standard prefix, it is useless to challenge it against // existing units. if (prefix != MeasureStandardPrefix.None) { return(!_allUnits.Values .OfType <AtomicMeasureUnit>() .Where(u => u.AutoStandardPrefix != AutoStandardPrefix.None) .SelectMany(u => MeasureStandardPrefix.GetPrefixes(u.AutoStandardPrefix) .Where(p => p != MeasureStandardPrefix.None) .Select(p => p.Abbreviation + u.Abbreviation)) .Any(exists => exists == a)); } return(true); }
bool TryParseExponent(Match match, out ExponentMeasureUnit u, bool skipFirstLookup = false) { if (!skipFirstLookup && TryGetExistingExponent(match.ToString(), out u)) { return(true); } u = null; // Handling dimensionless unit. var factor = match.Groups[4].Value; if (factor.Length > 0) { var f = ParseFactor(factor, ExpFactor.Neutral); u = RegisterPrefixed(f, MeasureStandardPrefix.None, MeasureUnit.None); return(true); } string sExp = match.Groups[3].Value; int exp = sExp.Length > 0 ? Int32.Parse(sExp) : 1; if (exp == 0) { u = MeasureUnit.None; return(true); } string withoutExp = match.Groups[1].Value + match.Groups[2].Value; if (_allUnits.TryGetValue(withoutExp, out var unit)) { if (exp == 1 && unit is ExponentMeasureUnit direct) { u = direct; return(true); } if (!(unit is AtomicMeasureUnit atomic)) { return(false); } u = RegisterExponent(exp, atomic); return(true); } ExpFactor adjustment = ExpFactor.Neutral; foreach (Capture f in match.Groups[1].Captures) { adjustment = ParseFactor(f.Value, adjustment); } string withoutAdjustment = match.Groups[2].Value; if (_allUnits.TryGetValue(withoutAdjustment, out unit)) { if (!(unit is AtomicMeasureUnit basic)) { return(false); } if (basic is PrefixedMeasureUnit prefix) { adjustment = adjustment.Multiply(prefix.AdjustmentFactor).Multiply(prefix.Prefix.Factor); basic = prefix.AtomicMeasureUnit; } u = CreateExponentPrefixed(exp, adjustment, basic); return(true); } var p = MeasureStandardPrefix.FindPrefix(withoutAdjustment); if (p == MeasureStandardPrefix.None) { return(false); } withoutAdjustment = withoutAdjustment.Substring(p.Abbreviation.Length); if (withoutAdjustment.Length == 0) { return(false); } if (_allUnits.TryGetValue(withoutAdjustment, out unit)) { if (!(unit is AtomicMeasureUnit basic)) { return(false); } if (basic is PrefixedMeasureUnit prefix) { return(false); } adjustment = adjustment.Multiply(p.Factor); u = CreateExponentPrefixed(exp, adjustment, basic); return(true); } return(false); }