/// <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);
        }
Exemplo n.º 3
0
        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);
        }