Ejemplo n.º 1
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);
        }
Ejemplo n.º 2
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);
        }
Ejemplo n.º 3
0
        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));
        }
Ejemplo n.º 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);
        }
Ejemplo n.º 5
0
        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);
        }
Ejemplo n.º 6
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));
        }
Ejemplo n.º 7
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));
        }
Ejemplo n.º 8
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));
        }
Ejemplo n.º 9
0
        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);
        }
Ejemplo n.º 10
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);
        }
Ejemplo n.º 11
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);
        }