diff --git a/src/mscorlib/src/System/Number.cs b/src/mscorlib/src/System/Number.cs index 3c1215d41823..c662e93cad36 100644 --- a/src/mscorlib/src/System/Number.cs +++ b/src/mscorlib/src/System/Number.cs @@ -622,16 +622,16 @@ internal unsafe struct NumberBuffer { if (*str == '\0') { return null; } - for (; (*str != '\0'); p++, str++) { - if (*p != *str) { //We only hurt the failure case - if ((*str == '\u00A0') && (*p == '\u0020')) {// This fix is for French or Kazakh cultures. Since a user cannot type 0xA0 as a - // space character we use 0x20 space character instead to mean the same. - continue; - } - return null; - } - } - return p; + // We only hurt the failure case + // This fix is for French or Kazakh cultures. Since a user cannot type 0xA0 as a + // space character we use 0x20 space character instead to mean the same. + while (*p == *str || (*str == '\u00a0' && *p == '\u0020')) + { + p++; + str++; + if (*str == '\0') return p; + } + return null; } [System.Security.SecuritySafeCritical] // auto-generated @@ -745,8 +745,6 @@ internal unsafe struct NumberBuffer { // The alternative currency symbol used in ANSI codepage, that can not roundtrip between ANSI and Unicode. // Currently, only ja-JP and ko-KR has non-null values (which is U+005c, backslash) string ansicurrSymbol = null; // currency symbol from NumberFormatInfo. - string altdecSep = null; // decimal separator from NumberFormatInfo as a decimal - string altgroupSep = null; // group separator from NumberFormatInfo as a decimal Boolean parsingCurrency = false; if ((options & NumberStyles.AllowCurrencySymbol) != 0) { @@ -760,8 +758,6 @@ internal unsafe struct NumberBuffer { // The idea here is to match the currency separators and on failure match the number separators to keep the perf of VB's IsNumeric fast. // The values of decSep are setup to use the correct relevant separator (currency in the if part and decimal in the else part). - altdecSep = numfmt.NumberDecimalSeparator; - altgroupSep = numfmt.NumberGroupSeparator; decSep = numfmt.CurrencyDecimalSeparator; groupSep = numfmt.CurrencyGroupSeparator; parsingCurrency = true; @@ -772,9 +768,7 @@ internal unsafe struct NumberBuffer { } Int32 state = 0; - Boolean signflag = false; // Cache the results of "options & PARSE_LEADINGSIGN && !(state & STATE_SIGN)" to avoid doing this twice Boolean bigNumber = (sb != null); // When a StringBuilder is provided then we use it in place of the number.digits char[50] - Boolean bigNumberHex = (bigNumber && ((options & NumberStyles.AllowHexSpecifier) != 0)); Int32 maxParseDigits = bigNumber ? Int32.MaxValue : NumberMaxDigits; char* p = str; @@ -784,32 +778,27 @@ internal unsafe struct NumberBuffer { while (true) { // Eat whitespace unless we've found a sign which isn't followed by a currency symbol. // "-Kr 1231.47" is legal but "- 1231.47" is not. - if (IsWhite(ch) && ((options & NumberStyles.AllowLeadingWhite) != 0) && (((state & StateSign) == 0) || (((state & StateSign) != 0) && (((state & StateCurrency) != 0) || numfmt.numberNegativePattern == 2)))) { - // Do nothing here. We will increase p at the end of the loop. - } - else if ((signflag = (((options & NumberStyles.AllowLeadingSign) != 0) && ((state & StateSign) == 0))) && ((next = MatchChars(p, numfmt.positiveSign)) != null)) { - state |= StateSign; - p = next - 1; - } else if (signflag && (next = MatchChars(p, numfmt.negativeSign)) != null) { - state |= StateSign; - number.sign = true; - p = next - 1; - } - else if (ch == '(' && ((options & NumberStyles.AllowParentheses) != 0) && ((state & StateSign) == 0)) { - state |= StateSign | StateParens; - number.sign = true; - } - else if ((currSymbol != null && (next = MatchChars(p, currSymbol)) != null) || (ansicurrSymbol != null && (next = MatchChars(p, ansicurrSymbol)) != null)) { - state |= StateCurrency; - currSymbol = null; - ansicurrSymbol = null; - // We already found the currency symbol. There should not be more currency symbols. Set - // currSymbol to NULL so that we won't search it again in the later code path. - p = next - 1; - } - else { - break; - } + if (!IsWhite(ch) || (options & NumberStyles.AllowLeadingWhite) == 0 || ((state & StateSign) != 0 && ((state & StateCurrency) == 0 && numfmt.NumberNegativePattern != 2))){ + if ((((options & NumberStyles.AllowLeadingSign) != 0) && (state & StateSign) == 0) && ((next = MatchChars(p, numfmt.PositiveSign)) != null || ((next = MatchChars(p, numfmt.NegativeSign)) != null && (number.sign = true)))){ + state |= StateSign; + p = next - 1; + } + else if (ch == '(' && ((options & NumberStyles.AllowParentheses) != 0) && ((state & StateSign) == 0)) { + state |= StateSign | StateParens; + number.sign = true; + } + else if ((currSymbol != null && (next = MatchChars(p, currSymbol)) != null) || (ansicurrSymbol != null && (next = MatchChars(p, ansicurrSymbol)) != null)) { + state |= StateCurrency; + currSymbol = null; + ansicurrSymbol = null; + // We already found the currency symbol. There should not be more currency symbols. Set + // currSymbol to NULL so that we won't search it again in the later code path. + p = next - 1; + } + else { + break; + } + } ch = *++p; } Int32 digCount = 0; @@ -818,7 +807,7 @@ internal unsafe struct NumberBuffer { if ((ch >= '0' && ch <= '9') || (((options & NumberStyles.AllowHexSpecifier) != 0) && ((ch >= 'a' && ch <= 'f') || (ch >= 'A' && ch <= 'F')))) { state |= StateDigits; - if (ch != '0' || (state & StateNonZero) != 0 || bigNumberHex) { + if (ch != '0' || (state & StateNonZero) != 0 || (bigNumber && ((options & NumberStyles.AllowHexSpecifier) != 0))) { if (digCount < maxParseDigits) { if (bigNumber) sb.Append(ch); @@ -837,11 +826,11 @@ internal unsafe struct NumberBuffer { number.scale--; } } - else if (((options & NumberStyles.AllowDecimalPoint) != 0) && ((state & StateDecimal) == 0) && ((next = MatchChars(p, decSep)) != null || ((parsingCurrency) && (state & StateCurrency) == 0) && (next = MatchChars(p, altdecSep)) != null)) { + else if (((options & NumberStyles.AllowDecimalPoint) != 0) && ((state & StateDecimal) == 0) && ((next = MatchChars(p, decSep)) != null || ((parsingCurrency) && (state & StateCurrency) == 0) && (next = MatchChars(p, numfmt.NumberDecimalSeparator)) != null)) { state |= StateDecimal; p = next - 1; } - else if (((options & NumberStyles.AllowThousands) != 0) && ((state & StateDigits) != 0) && ((state & StateDecimal) == 0) && ((next = MatchChars(p, groupSep)) != null || ((parsingCurrency) && (state & StateCurrency) == 0) && (next = MatchChars(p, altgroupSep)) != null)) { + else if (((options & NumberStyles.AllowThousands) != 0) && ((state & StateDigits) != 0) && ((state & StateDecimal) == 0) && ((next = MatchChars(p, groupSep)) != null || ((parsingCurrency) && (state & StateCurrency) == 0) && (next = MatchChars(p, numfmt.NumberGroupSeparator)) != null)) { p = next - 1; } else { @@ -890,27 +879,23 @@ internal unsafe struct NumberBuffer { } } while (true) { - if (IsWhite(ch) && ((options & NumberStyles.AllowTrailingWhite) != 0)) { - } - else if ((signflag = (((options & NumberStyles.AllowTrailingSign) != 0) && ((state & StateSign) == 0))) && (next = MatchChars(p, numfmt.positiveSign)) != null) { - state |= StateSign; - p = next - 1; - } else if (signflag && (next = MatchChars(p, numfmt.negativeSign)) != null) { - state |= StateSign; - number.sign = true; - p = next - 1; - } - else if (ch == ')' && ((state & StateParens) != 0)) { - state &= ~StateParens; - } - else if ((currSymbol != null && (next = MatchChars(p, currSymbol)) != null) || (ansicurrSymbol != null && (next = MatchChars(p, ansicurrSymbol)) != null)) { - currSymbol = null; - ansicurrSymbol = null; - p = next - 1; - } - else { - break; - } + if (!IsWhite(ch) || (options & NumberStyles.AllowTrailingWhite) == 0){ + if (((options & NumberStyles.AllowTrailingSign) != 0 && ((state & StateSign) == 0)) && ((next = MatchChars(p, numfmt.PositiveSign)) != null || (((next = MatchChars(p, numfmt.NegativeSign)) != null) && (number.sign = true)))) { + state |= StateSign; + p = next - 1; + } + else if (ch == ')' && ((state & StateParens) != 0)) { + state &= ~StateParens; + } + else if ((currSymbol != null && (next = MatchChars(p, currSymbol)) != null) || (ansicurrSymbol != null && (next = MatchChars(p, ansicurrSymbol)) != null)) { + currSymbol = null; + ansicurrSymbol = null; + p = next - 1; + } + else { + break; + } + } ch = *++p; } if ((state & StateParens) == 0) {