static int ScanHexBin <T>(int i, IParserSupport <T> p, int maxDigits, HexBinParser <T> parser) { string expr = p.Expression; T value = default(T); int begin = i; for (; i < expr.Length; i++) { if (!parser(expr[i], ref value)) { break; } } int len = i - begin; if (len == 0) { p.ParsedValue = value; return(1); } if (len > maxDigits) { throw p.InvalidNumberFormat( Resource.errNumberOverflow, Substring(i, p), null); } p.ParsedValue = value; return(len + 2); }
public int TryParse(int i, IParserSupport <long> p) { string expr = p.Expression; if (expr[i] < '0' || expr[i] > '9') { return(-1); } return(Parse(i, p, Int64.Parse, ScanInt64Hex, ScanInt64Bin)); }
public int TryParse(int i, IParserSupport <decimal> p) { string expr = p.Expression; if ((expr[i] < '0' || expr[i] > '9') && expr[i] != p.DecimalDot) { return(-1); } return(Parse(i, p, Decimal.Parse)); }
static int ScanInt64Bin(int i, IParserSupport <long> p) { return(ScanHexBin(i, p, 64, (char c, ref long x) => { if (c == '0') { x <<= 1; return true; } if (c == '1') { x <<= 1; x |= 1; return true; } return false; })); }
static int ScanInt64Hex(int i, IParserSupport <long> p) { return(ScanHexBin(i, p, 16, (char c, ref long x) => { int digit = HexDigit(c); if (digit < 0) { return false; } x *= 0x10; x += digit; return true; })); }
static int ScanInt32Bin(int i, IParserSupport <int> p) { return(ScanHexBin(i, p, 32, (char c, ref int x) => { if (c == '0') { x <<= 1; return true; } if (c == '1') { x <<= 1; x |= 1; return true; } return false; })); }
static int ScanInt32Hex(int i, IParserSupport <int> p) { return(ScanHexBin(i, p, 8, (char c, ref int x) => { int digit = HexDigit(c); if (digit < 0) { return false; } x *= 0x10; x += digit; return true; })); }
static int Parse <T>(int i, IParserSupport <T> p, Parser <T> parser) { var str = ScanNumber(i, p); if (str == null) { return(-1); } bool neg = p.DiscardNegate(); try { if (neg) { p.ParsedValue = parser( p.NumberFormat.NegativeSign + str, NumberStyles.AllowLeadingSign | NumberStyles.AllowDecimalPoint | NumberStyles.AllowExponent, p.NumberFormat); } else { p.ParsedValue = parser(str, NumberStyles.AllowDecimalPoint | NumberStyles.AllowExponent, p.NumberFormat); } return(str.Length); } catch (FormatException e) { throw p.InvalidNumberFormat( Resource.errNumberFormat, str, e); } catch (OverflowException e) { throw p.InvalidNumberFormat( Resource.errNumberOverflow, str, e); } }
static string Substring <T>(int i, IParserSupport <T> p) { return(p.Expression.Substring( p.BeginPos, i - p.BeginPos)); }
public int TryParse(int i, IParserSupport <T> p) { return(-1); }
static int Parse <T>( int i, IParserSupport <T> p, Parser <T> parser, HexBinScan <T> hex, HexBinScan <T> bin) { string expr = p.Expression; if (expr[i] < '0' || expr[i] > '9') { return(-1); } // hex/bin literal support: if (expr[i] == '0' && i + 1 < expr.Length) { i++; char c = expr[i++]; if (c == 'x' || c == 'X') { return(hex(i, p)); } if (c == 'b' || c == 'B') { return(bin(i, p)); } p.ParsedValue = default(T); return(1); } // skip digits and parse: while (IsDigit(expr, i)) { i++; } string str = Substring(i, p); bool neg = p.DiscardNegate(); try { if (neg) { p.ParsedValue = parser( p.NumberFormat.NegativeSign + str, NumberStyles.AllowLeadingSign | NumberStyles.AllowDecimalPoint | NumberStyles.AllowExponent, p.NumberFormat); } else { p.ParsedValue = parser(str, NumberStyles.AllowDecimalPoint | NumberStyles.AllowExponent, p.NumberFormat); } return(str.Length); } catch (FormatException e) { throw p.InvalidNumberFormat( Resource.errNumberFormat, str, e); } catch (OverflowException e) { throw p.InvalidNumberFormat( Resource.errNumberOverflow, str, e); } }
static string ScanNumber <T>(int i, IParserSupport <T> p) { string expr = p.Expression; // Fractal part: ========================== // numbers not like ".123": if (expr[i] != p.DecimalDot) { // skip digits and decimal point: for (; i < expr.Length; i++) { if (expr[i] >= '0' && expr[i] <= '9') { continue; } if (expr[i] == p.DecimalDot) { i++; } break; } } else { if (!IsDigit(expr, ++i)) { return(null); } } // skip digits: while (IsDigit(expr, i)) { i++; } // Exponental part: ======================= // at least 2 chars: if (i + 1 < expr.Length) { // E character: char c = expr[i]; if (c == 'e' || c == 'E') { int j = i; // exponetal sign: c = expr[++j]; if (c == '-' || c == '+') { j++; } // exponental value: if (IsDigit(expr, j++)) { while (IsDigit(expr, j)) { j++; } i = j; } } } return(expr.Substring(p.BeginPos, i - p.BeginPos)); }