Skip to content
This repository was archived by the owner on Jan 23, 2023. It is now read-only.
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
117 changes: 51 additions & 66 deletions src/mscorlib/src/System/Number.cs
Original file line number Diff line number Diff line change
Expand Up @@ -622,16 +622,16 @@ private unsafe static Boolean NumberToUInt64(ref NumberBuffer number, ref UInt64
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
Expand Down Expand Up @@ -745,8 +745,6 @@ private unsafe static Boolean ParseNumber(ref char * str, NumberStyles options,
// 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) {
Expand All @@ -760,8 +758,6 @@ private unsafe static Boolean ParseNumber(ref char * str, NumberStyles options,

// 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;
Expand All @@ -772,9 +768,7 @@ private unsafe static Boolean ParseNumber(ref char * str, NumberStyles options,
}

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;
Expand All @@ -784,32 +778,27 @@ private unsafe static Boolean ParseNumber(ref char * str, NumberStyles options,
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;
Expand All @@ -818,7 +807,7 @@ private unsafe static Boolean ParseNumber(ref char * str, NumberStyles options,
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);
Expand All @@ -837,11 +826,11 @@ private unsafe static Boolean ParseNumber(ref char * str, NumberStyles options,
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 {
Expand Down Expand Up @@ -890,27 +879,23 @@ private unsafe static Boolean ParseNumber(ref char * str, NumberStyles options,
}
}
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) {
Expand Down