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); }
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)); }
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); }
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); }
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); } } }
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)); }
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. }
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)); }
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); }
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); }
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); }