Exemple #1
0
        private static bool TryReadSuperScriptPower(string text, ref int pos, out int power)
        {
            if (!text[pos].IsSuperscriptDigitOrSign())
            {
                power = 0;
                return(false);
            }

            var sign = TryReadSuperScriptSign(text, ref pos);

            if (sign == Sign.None)
            {
                sign = Sign.Positive;
            }

            if (TryReadSuperScriptSign(text, ref pos) != Sign.None)
            {
                // not allowing a⁻⁻² as it is most likely a typo
                power = 0;
                return(false);
            }

            WhiteSpaceReader.TryRead(text, ref pos);
            if (TryReadSuperScriptInt(text, ref pos, out power))
            {
                power *= (int)sign;
                return(true);
            }

            power = 0;
            return(false);
        }
Exemple #2
0
        internal static bool TryRead(string text, out IReadOnlyList <SymbolAndPower> result)
        {
            var pos     = 0;
            var success = TryRead(text, ref pos, out result);

            return(success && WhiteSpaceReader.IsRestWhiteSpace(text, pos));
        }
Exemple #3
0
        private static bool TryReadHatPower(string text, ref int pos, out int power)
        {
            if (text[pos] != '^')
            {
                // leaving this even if it is a try method. Getting here means something should have been checked before
                throw new InvalidOperationException("Check that there is a hat power to read before calling this");
            }

            pos++;
            WhiteSpaceReader.TryRead(text, ref pos);

            var ps = OperatorReader.TryReadSign(text, ref pos);

            if (ps == Sign.None)
            {
                ps = Sign.Positive;
            }

            if (OperatorReader.TryReadSign(text, ref pos) != Sign.None)
            {
                // not allowing a^--2 as it is most likely a typo
                power = 0;
                return(false);
            }

            WhiteSpaceReader.TryRead(text, ref pos);
            if (IntReader.TryReadInt32(text, ref pos, out power))
            {
                power *= (int)ps;
                return(true);
            }

            power = 0;
            return(false);
        }
Exemple #4
0
        internal static bool TryParse(string text, ref int pos, out TUnit result)
        {
            var start = pos;

            if (UnitFormatCache <TUnit> .Cache.TryGetUnitForSymbol(text, ref pos, out result))
            {
                return(true);
            }

            if (SymbolAndPowerReader.TryRead(text, ref pos, out IReadOnlyList <SymbolAndPower> symbolsAndPowers))
            {
                var symbol = text.Substring(start, pos - start);
                WhiteSpaceReader.TryRead(text, ref pos, out string _);
                if (!IsEndOfSymbol(text, pos))
                {
                    result = Unit <TUnit> .Default;
                    return(false);
                }

                if (UnitFormatCache <TUnit> .Cache.TryGetUnitForParts(symbolsAndPowers, out result))
                {
                    UnitFormatCache <TUnit> .Cache.Add(symbol, symbolsAndPowers);

                    UnitFormatCache <TUnit> .Cache.Add(symbol, result);

                    return(true);
                }
            }

            pos    = start;
            result = Unit <TUnit> .Default;
            return(false);
        }
        internal static bool TryParse <TUnit, TQuantity>(string text, Func <double, TUnit, TQuantity> creator, NumberStyles style, IFormatProvider provider, out TQuantity value)
            where TQuantity : struct, IQuantity <TUnit>
            where TUnit : struct, IUnit, IEquatable <TUnit>
        {
            var pos = 0;

            _ = WhiteSpaceReader.TryRead(text, ref pos);
            if (!DoubleReader.TryRead(text, ref pos, style, provider, out var d))
            {
                value = default;
                return(false);
            }

            _ = WhiteSpaceReader.TryRead(text, ref pos);

            if (!UnitParser <TUnit> .TryParse(text, ref pos, out var unit))
            {
                value = default;
                return(false);
            }

            _ = WhiteSpaceReader.TryRead(text, ref pos);
            if (pos != text.Length)
            {
                value = default;
                return(false);
            }

            value = creator(d, unit);
            return(true);
        }
        internal static TQuantity Parse <TUnit, TQuantity>(string text, Func <double, TUnit, TQuantity> creator, NumberStyles style, IFormatProvider provider)
            where TQuantity : IQuantity <TUnit>
            where TUnit : struct, IUnit, IEquatable <TUnit>
        {
            var pos = 0;

            _ = WhiteSpaceReader.TryRead(text, ref pos);

            if (!DoubleReader.TryRead(text, ref pos, style, provider, out var d))
            {
                throw new FormatException("Could not parse the scalar value from: " + text);
            }

            _ = WhiteSpaceReader.TryRead(text, ref pos);
            if (!UnitParser <TUnit> .TryParse(text, ref pos, out var unit))
            {
                throw new FormatException("Could not parse the unit value from: " + text);
            }

            _ = WhiteSpaceReader.TryRead(text, ref pos);
            if (pos != text.Length)
            {
                throw new FormatException("Could not parse the unit value from: " + text);
            }

            return(creator(d, unit));
        }
        internal static PaddedFormat GetOrCreate(string format)
        {
            if (String.IsNullOrEmpty(format))
            {
                return(PaddedFormat.NullFormat);
            }

            PaddedFormat match;

            if (Cache.TryGet(format, out match))
            {
                return(match);
            }

            int pos          = 0;
            var paddedFormat = GetOrCreate(format, ref pos);

            if (!WhiteSpaceReader.IsRestWhiteSpace(format, pos))
            {
                paddedFormat = paddedFormat.AsUnknownFormat();
            }

            Cache.Add(format, paddedFormat);
            return(paddedFormat);
        }
Exemple #8
0
            internal Caches()
            {
                var units = GetUnits();

                foreach (var unit in units)
                {
                    this.symbolUnitMap.Add(unit.Symbol, unit);

                    var pos = 0;
                    if (SymbolAndPowerReader.TryRead(unit.Symbol, ref pos, out IReadOnlyList <SymbolAndPower> result))
                    {
                        if (!WhiteSpaceReader.IsRestWhiteSpace(unit.Symbol, pos))
                        {
                            throw new InvalidOperationException($"Failed splitting {((IUnit)unit).Symbol} into {nameof(SymbolAndPower)}");
                        }

                        if (result.Count == 0)
                        {
                            throw new InvalidOperationException($"Did not find any parts in {unit.Symbol}");
                        }

                        this.symbolPartsMap.Add(unit.Symbol, result);
                        var sapSet = new ReadonlySet <SymbolAndPower>(result);
                        this.unitPartsMap.TryAdd(sapSet, unit);
                    }
                }
            }
Exemple #9
0
        internal static bool TryParse(string text, out TUnit value)
        {
            var pos = 0;

            WhiteSpaceReader.TryRead(text, ref pos);
            return(TryParse(text, ref pos, out value) &&
                   WhiteSpaceReader.IsRestWhiteSpace(text, pos));
        }
Exemple #10
0
        private static bool IsEndOfSymbol(string text, int pos)
        {
            if (pos == text.Length)
            {
                return(true);
            }

            return(text[pos] == '}' || WhiteSpaceReader.IsRestWhiteSpace(text, pos));
        }
        internal static bool TryRead(string text, [NotNullWhen(true)] out IReadOnlyList <SymbolAndPower>?result)
        {
            var pos     = 0;
            var success = TryRead(text, ref pos, out result);

#pragma warning disable CS8762 // Parameter must have a non-null value when exiting in some condition.
            return(success && WhiteSpaceReader.IsRestWhiteSpace(text, pos));

#pragma warning restore CS8762 // Parameter must have a non-null value when exiting in some condition.
        }
Exemple #12
0
        internal static PaddedFormat GetOrCreate(string format, ref int pos, out TUnit unit)
        {
            var start = pos;

            WhiteSpaceReader.TryRead(format, ref pos, out string prePadding);
            if (format == null ||
                pos == format.Length)
            {
                pos  = start;
                unit = Unit <TUnit> .Default;
                return(PaddedFormat.CreateUnknown(prePadding, null));
            }

            if (Cache.TryGetUnitForSymbol(format, ref pos, out string symbol, out unit))
            {
                if (WhiteSpaceReader.IsRestWhiteSpace(format, pos))
                {
                    WhiteSpaceReader.TryRead(format, ref pos, out string postPadding);
                    return(new PaddedFormat(prePadding, symbol, postPadding));
                }

                pos -= symbol.Length;
            }

            if (SymbolAndPowerReader.TryRead(format, ref pos, out IReadOnlyList <SymbolAndPower> symbolsAndPowers))
            {
                symbol = format.Substring(start, pos - start);

                WhiteSpaceReader.TryRead(format, ref pos, out string postPadding);
                if (!WhiteSpaceReader.IsRestWhiteSpace(format, pos))
                {
                    pos  = start;
                    unit = Unit <TUnit> .Default;
                    return(PaddedFormat.CreateUnknown(prePadding, format.Substring(start)));
                }

                if (Cache.TryGetUnitForParts(symbolsAndPowers, out unit))
                {
                    Cache.Add(symbol, symbolsAndPowers);
                    Cache.Add(symbol, unit);
                }
                else
                {
                    pos  = start;
                    unit = Unit <TUnit> .Default;
                    return(PaddedFormat.CreateUnknown(prePadding, format.Substring(start)));
                }

                return(new PaddedFormat(prePadding, symbol, postPadding));
            }

            pos = start;
            return(PaddedFormat.CreateUnknown(prePadding, format));
        }
Exemple #13
0
        internal static PaddedFormat GetOrCreate(string format, ref int pos)
        {
            string prePadding;

            WhiteSpaceReader.TryRead(format, ref pos, out prePadding);
            string valueFormat;

            if (DoubleFormatReader.TryRead(format, ref pos, out valueFormat))
            {
                string postPadding;
                WhiteSpaceReader.TryRead(format, ref pos, out postPadding);
                return(new PaddedFormat(prePadding, valueFormat, postPadding));
            }

            return(PaddedFormat.CreateUnknown(prePadding, format));
        }
        internal static bool TryRead(string text, ref int pos, out SymbolAndPower result)
        {
            if (pos == text.Length)
            {
                result = default(SymbolAndPower);
                return(false);
            }

            var start = pos;

            while (text.Length > pos && IsSymbol(text[pos]))
            {
                pos++;
            }

            if (pos == start)
            {
                result = default(SymbolAndPower);
                return(false);
            }

            var symbol = text.Substring(start, pos - start);

            WhiteSpaceReader.TryRead(text, ref pos);
            int power;

            if (!PowerReader.TryRead(text, ref pos, out power))
            {
                pos    = start;
                result = default(SymbolAndPower);
                return(false);
            }

            if (power == 0 || Math.Abs(power) > 5) // 5 > is most likely a typo right?
            {
                pos    = start;
                result = default(SymbolAndPower);
                return(false);
            }

            result = new SymbolAndPower(symbol, power);
            return(true);
        }
Exemple #15
0
        internal static bool TryRead(string text, ref int pos, out IReadOnlyList <SymbolAndPower> result)
        {
            var start = pos;
            var sign  = Sign.Positive;
            List <SymbolAndPower> saps = null;

            while (pos < text.Length)
            {
                WhiteSpaceReader.TryRead(text, ref pos);
                if (!TryRead(text, ref pos, out SymbolAndPower sap))
                {
                    pos    = start;
                    result = null;
                    return(false);
                }

                if (sap.Power < 0 &&
                    sign == Sign.Negative)
                {
                    pos    = start;
                    result = null;
                    return(false);
                }

                if (sign == Sign.Negative)
                {
                    sap = new SymbolAndPower(sap.Symbol, -1 * sap.Power);
                }

                if (saps == null)
                {
                    saps = new List <SymbolAndPower>();
                }

                saps.Add(sap);

                var op = OperatorReader.TryReadMultiplyOrDivide(text, ref pos);
                if (op != MultiplyOrDivide.None)
                {
                    WhiteSpaceReader.TryRead(text, ref pos);
                    if (OperatorReader.TryReadMultiplyOrDivide(text, ref pos) != MultiplyOrDivide.None)
                    {
                        pos    = start;
                        result = null;
                        return(false);
                    }

                    if (op == MultiplyOrDivide.Division)
                    {
                        if (sign == Sign.Negative)
                        {
                            pos    = start;
                            result = null;
                            return(false);
                        }

                        sign = Sign.Negative;
                    }
                }
            }

            if (saps == null || !IsUnique(saps))
            {
                result = null;
                return(false);
            }

            result = saps;
            return(true);
        }
Exemple #16
0
        internal static bool TryRead(
            string text,
            ref int pos,
            NumberStyles style,
            IFormatProvider provider,
            out double result)
        {
            result = 0;
            var start = pos;

            if (string.IsNullOrEmpty(text))
            {
                return(false);
            }

            if (!IsValidFloatingPointStyle(style))
            {
                return(false);
            }

            if ((style & NumberStyles.AllowHexSpecifier) != 0)
            {
                return(false);
            }

            if ((style & NumberStyles.AllowLeadingWhite) != 0)
            {
                _ = WhiteSpaceReader.TryRead(text, ref pos);
            }

            if (char.IsWhiteSpace(text[pos]))
            {
                return(false);
            }

            if (TrySkipDoubleDigits(text, ref pos, style, provider))
            {
                return(TryParseSubString(text, start, ref pos, style, provider, out result));
            }

            if (provider is null)
            {
                provider = CultureInfo.CurrentCulture;
            }

            var format = NumberFormatInfo.GetInstance(provider);

            if (Skipper.TrySkip(text, ref pos, format.NaNSymbol))
            {
                result = double.NaN;
                return(true);
            }

            if (Skipper.TrySkip(text, ref pos, format.PositiveInfinitySymbol))
            {
                result = double.PositiveInfinity;
                return(true);
            }

            if (Skipper.TrySkip(text, ref pos, format.NegativeInfinitySymbol))
            {
                result = double.NegativeInfinity;
                return(true);
            }

            pos = start;
            return(false);
        }