summaryrefslogtreecommitdiff
path: root/src/mscorlib/src/System/Number.cs
diff options
context:
space:
mode:
Diffstat (limited to 'src/mscorlib/src/System/Number.cs')
-rw-r--r--src/mscorlib/src/System/Number.cs782
1 files changed, 475 insertions, 307 deletions
diff --git a/src/mscorlib/src/System/Number.cs b/src/mscorlib/src/System/Number.cs
index 66d05673a6..b30d4e643f 100644
--- a/src/mscorlib/src/System/Number.cs
+++ b/src/mscorlib/src/System/Number.cs
@@ -2,18 +2,19 @@
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
-namespace System {
-
- using System;
- using System.Globalization;
- using System.Runtime;
- using System.Runtime.CompilerServices;
- using System.Runtime.Versioning;
- using System.Security;
- using System.Text;
- using System.Diagnostics;
- using System.Diagnostics.Contracts;
+using System;
+using System.Globalization;
+using System.Runtime;
+using System.Runtime.CompilerServices;
+using System.Runtime.Versioning;
+using System.Security;
+using System.Text;
+using System.Diagnostics;
+using System.Diagnostics.Contracts;
+
+namespace System
+{
// The Number class implements methods for formatting and parsing
// numeric values. To format and parse numeric values, applications should
// use the Format and Parse methods provided by the numeric
@@ -287,9 +288,10 @@ namespace System {
[System.Runtime.CompilerServices.FriendAccessAllowed]
internal class Number
{
- private Number() {
+ private Number()
+ {
}
-
+
[MethodImplAttribute(MethodImplOptions.InternalCall)]
public static extern String FormatDecimal(Decimal value, String format, NumberFormatInfo info);
[MethodImplAttribute(MethodImplOptions.InternalCall)]
@@ -304,7 +306,7 @@ namespace System {
public static extern String FormatUInt64(ulong value, String format, NumberFormatInfo info);
[MethodImplAttribute(MethodImplOptions.InternalCall)]
public static extern String FormatSingle(float value, String format, NumberFormatInfo info);
-
+
[MethodImplAttribute(MethodImplOptions.InternalCall)]
public unsafe static extern Boolean NumberBufferToDecimal(byte* number, ref Decimal value);
[MethodImplAttribute(MethodImplOptions.InternalCall)]
@@ -332,27 +334,29 @@ namespace System {
// structure, except for the digits, and pack those values into the byte buffer
// if called out to managed.
[System.Runtime.CompilerServices.FriendAccessAllowed]
- internal unsafe struct NumberBuffer {
-
+ internal unsafe struct NumberBuffer
+ {
// Enough space for NumberMaxDigit characters plus null and 3 32 bit integers and a pointer
public static readonly Int32 NumberBufferBytes = 12 + ((NumberMaxDigits + 1) * 2) + IntPtr.Size;
- private Byte * baseAddress;
- public Char * digits;
+ private Byte* baseAddress;
+ public Char* digits;
public Int32 precision;
public Int32 scale;
public Boolean sign;
- public NumberBuffer(Byte* stackBuffer) {
- this.baseAddress = stackBuffer;
- this.digits = (((Char*) stackBuffer) + 6);
+ public NumberBuffer(Byte* stackBuffer)
+ {
+ baseAddress = stackBuffer;
+ this.digits = (((Char*)stackBuffer) + 6);
this.precision = 0;
this.scale = 0;
this.sign = false;
}
- public Byte* PackForNative() {
- Int32* baseInteger = (Int32*) baseAddress;
+ public Byte* PackForNative()
+ {
+ Int32* baseInteger = (Int32*)baseAddress;
baseInteger[0] = precision;
baseInteger[1] = scale;
baseInteger[2] = sign ? 1 : 0;
@@ -360,55 +364,67 @@ namespace System {
}
}
- private static Boolean HexNumberToInt32(ref NumberBuffer number, ref Int32 value) {
+ private static Boolean HexNumberToInt32(ref NumberBuffer number, ref Int32 value)
+ {
UInt32 passedValue = 0;
Boolean returnValue = HexNumberToUInt32(ref number, ref passedValue);
value = (Int32)passedValue;
return returnValue;
}
- private static Boolean HexNumberToInt64(ref NumberBuffer number, ref Int64 value) {
+ private static Boolean HexNumberToInt64(ref NumberBuffer number, ref Int64 value)
+ {
UInt64 passedValue = 0;
Boolean returnValue = HexNumberToUInt64(ref number, ref passedValue);
value = (Int64)passedValue;
return returnValue;
}
- private unsafe static Boolean HexNumberToUInt32(ref NumberBuffer number, ref UInt32 value) {
-
+ private unsafe static Boolean HexNumberToUInt32(ref NumberBuffer number, ref UInt32 value)
+ {
Int32 i = number.scale;
- if (i > UInt32Precision || i < number.precision) {
+ if (i > UInt32Precision || i < number.precision)
+ {
return false;
}
Char* p = number.digits;
Debug.Assert(p != null, "");
UInt32 n = 0;
- while (--i >= 0) {
- if (n > ((UInt32)0xFFFFFFFF / 16)) {
+ while (--i >= 0)
+ {
+ if (n > ((UInt32)0xFFFFFFFF / 16))
+ {
return false;
}
n *= 16;
- if (*p != '\0') {
+ if (*p != '\0')
+ {
UInt32 newN = n;
- if (*p != '\0') {
- if (*p >= '0' && *p <= '9') {
+ if (*p != '\0')
+ {
+ if (*p >= '0' && *p <= '9')
+ {
newN += (UInt32)(*p - '0');
}
- else {
- if (*p >= 'A' && *p <= 'F') {
+ else
+ {
+ if (*p >= 'A' && *p <= 'F')
+ {
newN += (UInt32)((*p - 'A') + 10);
}
- else {
+ else
+ {
Debug.Assert(*p >= 'a' && *p <= 'f', "");
newN += (UInt32)((*p - 'a') + 10);
}
}
p++;
}
-
+
// Detect an overflow here...
- if (newN < n) {
+ if (newN < n)
+ {
return false;
}
n = newN;
@@ -418,41 +434,51 @@ namespace System {
return true;
}
- private unsafe static Boolean HexNumberToUInt64(ref NumberBuffer number, ref UInt64 value) {
-
+ private unsafe static Boolean HexNumberToUInt64(ref NumberBuffer number, ref UInt64 value)
+ {
Int32 i = number.scale;
- if (i > UInt64Precision || i < number.precision) {
+ if (i > UInt64Precision || i < number.precision)
+ {
return false;
}
Char* p = number.digits;
Debug.Assert(p != null, "");
-
+
UInt64 n = 0;
- while (--i >= 0) {
- if (n > (0xFFFFFFFFFFFFFFFF / 16)) {
+ while (--i >= 0)
+ {
+ if (n > (0xFFFFFFFFFFFFFFFF / 16))
+ {
return false;
}
n *= 16;
- if (*p != '\0') {
- UInt64 newN = n;
- if (*p != '\0') {
- if (*p >= '0' && *p <= '9') {
+ if (*p != '\0')
+ {
+ UInt64 newN = n;
+ if (*p != '\0')
+ {
+ if (*p >= '0' && *p <= '9')
+ {
newN += (UInt64)(*p - '0');
}
- else {
- if (*p >= 'A' && *p <= 'F') {
+ else
+ {
+ if (*p >= 'A' && *p <= 'F')
+ {
newN += (UInt64)((*p - 'A') + 10);
}
- else {
+ else
+ {
Debug.Assert(*p >= 'a' && *p <= 'f', "");
newN += (UInt64)((*p - 'a') + 10);
}
}
p++;
}
-
+
// Detect an overflow here...
- if (newN < n) {
+ if (newN < n)
+ {
return false;
}
n = newN;
@@ -462,36 +488,45 @@ namespace System {
return true;
}
- private static Boolean IsWhite(char ch) {
+ private static Boolean IsWhite(char ch)
+ {
return (((ch) == 0x20) || ((ch) >= 0x09 && (ch) <= 0x0D));
}
- private unsafe static Boolean NumberToInt32(ref NumberBuffer number, ref Int32 value) {
-
+ private unsafe static Boolean NumberToInt32(ref NumberBuffer number, ref Int32 value)
+ {
Int32 i = number.scale;
- if (i > Int32Precision || i < number.precision) {
+ if (i > Int32Precision || i < number.precision)
+ {
return false;
}
- char * p = number.digits;
+ char* p = number.digits;
Debug.Assert(p != null, "");
Int32 n = 0;
- while (--i >= 0) {
- if ((UInt32)n > (0x7FFFFFFF / 10)) {
+ while (--i >= 0)
+ {
+ if ((UInt32)n > (0x7FFFFFFF / 10))
+ {
return false;
}
n *= 10;
- if (*p != '\0') {
+ if (*p != '\0')
+ {
n += (Int32)(*p++ - '0');
}
}
- if (number.sign) {
+ if (number.sign)
+ {
n = -n;
- if (n > 0) {
+ if (n > 0)
+ {
return false;
}
}
- else {
- if (n < 0) {
+ else
+ {
+ if (n < 0)
+ {
return false;
}
}
@@ -499,32 +534,40 @@ namespace System {
return true;
}
- private unsafe static Boolean NumberToInt64(ref NumberBuffer number, ref Int64 value) {
-
+ private unsafe static Boolean NumberToInt64(ref NumberBuffer number, ref Int64 value)
+ {
Int32 i = number.scale;
- if (i > Int64Precision || i < number.precision) {
+ if (i > Int64Precision || i < number.precision)
+ {
return false;
}
char* p = number.digits;
Debug.Assert(p != null, "");
Int64 n = 0;
- while (--i >= 0) {
- if ((UInt64)n > (0x7FFFFFFFFFFFFFFF / 10)) {
+ while (--i >= 0)
+ {
+ if ((UInt64)n > (0x7FFFFFFFFFFFFFFF / 10))
+ {
return false;
}
n *= 10;
- if (*p != '\0') {
+ if (*p != '\0')
+ {
n += (Int32)(*p++ - '0');
}
}
- if (number.sign) {
+ if (number.sign)
+ {
n = -n;
- if (n > 0) {
+ if (n > 0)
+ {
return false;
}
}
- else {
- if (n < 0) {
+ else
+ {
+ if (n < 0)
+ {
return false;
}
}
@@ -532,24 +575,29 @@ namespace System {
return true;
}
- private unsafe static Boolean NumberToUInt32(ref NumberBuffer number, ref UInt32 value) {
-
+ private unsafe static Boolean NumberToUInt32(ref NumberBuffer number, ref UInt32 value)
+ {
Int32 i = number.scale;
- if (i > UInt32Precision || i < number.precision || number.sign ) {
+ if (i > UInt32Precision || i < number.precision || number.sign)
+ {
return false;
}
char* p = number.digits;
Debug.Assert(p != null, "");
UInt32 n = 0;
- while (--i >= 0) {
- if (n > (0xFFFFFFFF / 10)) {
+ while (--i >= 0)
+ {
+ if (n > (0xFFFFFFFF / 10))
+ {
return false;
}
n *= 10;
- if (*p != '\0') {
+ if (*p != '\0')
+ {
UInt32 newN = n + (UInt32)(*p++ - '0');
// Detect an overflow here...
- if (newN < n) {
+ if (newN < n)
+ {
return false;
}
n = newN;
@@ -559,24 +607,29 @@ namespace System {
return true;
}
- private unsafe static Boolean NumberToUInt64(ref NumberBuffer number, ref UInt64 value) {
-
+ private unsafe static Boolean NumberToUInt64(ref NumberBuffer number, ref UInt64 value)
+ {
Int32 i = number.scale;
- if (i > UInt64Precision || i < number.precision || number.sign) {
+ if (i > UInt64Precision || i < number.precision || number.sign)
+ {
return false;
}
- char * p = number.digits;
+ char* p = number.digits;
Debug.Assert(p != null, "");
UInt64 n = 0;
- while (--i >= 0) {
- if (n > (0xFFFFFFFFFFFFFFFF / 10)) {
+ while (--i >= 0)
+ {
+ if (n > (0xFFFFFFFFFFFFFFFF / 10))
+ {
return false;
}
n *= 10;
- if (*p != '\0') {
+ if (*p != '\0')
+ {
UInt64 newN = n + (UInt64)(*p++ - '0');
// Detect an overflow here...
- if (newN < n) {
+ if (newN < n)
+ {
return false;
}
n = newN;
@@ -586,20 +639,24 @@ namespace System {
return true;
}
- private unsafe static char * MatchChars(char* p, string str) {
- fixed (char* stringPointer = str) {
+ private unsafe static char* MatchChars(char* p, string str)
+ {
+ fixed (char* stringPointer = str)
+ {
return MatchChars(p, stringPointer);
}
}
- private unsafe static char * MatchChars(char* p, char* str) {
+ private unsafe static char* MatchChars(char* p, char* str)
+ {
Debug.Assert(p != null && str != null, "");
- if (*str == '\0') {
+ if (*str == '\0')
+ {
return null;
}
- // 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.
+ // 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++;
@@ -609,96 +666,113 @@ namespace System {
return null;
}
- internal unsafe static Decimal ParseDecimal(String value, NumberStyles options, NumberFormatInfo numfmt) {
-
- Byte * numberBufferBytes = stackalloc Byte[NumberBuffer.NumberBufferBytes];
+ internal unsafe static Decimal ParseDecimal(String value, NumberStyles options, NumberFormatInfo numfmt)
+ {
+ Byte* numberBufferBytes = stackalloc Byte[NumberBuffer.NumberBufferBytes];
NumberBuffer number = new NumberBuffer(numberBufferBytes);
Decimal result = 0;
-
+
StringToNumber(value, options, ref number, numfmt, true);
- if (!NumberBufferToDecimal(number.PackForNative(), ref result)) {
- throw new OverflowException(Environment.GetResourceString("Overflow_Decimal"));
+ if (!NumberBufferToDecimal(number.PackForNative(), ref result))
+ {
+ throw new OverflowException(SR.Overflow_Decimal);
}
return result;
}
- internal unsafe static Double ParseDouble(String value, NumberStyles options, NumberFormatInfo numfmt) {
- if (value == null) {
+ internal unsafe static Double ParseDouble(String value, NumberStyles options, NumberFormatInfo numfmt)
+ {
+ if (value == null)
+ {
throw new ArgumentNullException(nameof(value));
}
- Byte * numberBufferBytes = stackalloc Byte[NumberBuffer.NumberBufferBytes];
+ Byte* numberBufferBytes = stackalloc Byte[NumberBuffer.NumberBufferBytes];
NumberBuffer number = new NumberBuffer(numberBufferBytes);
Double d = 0;
-
- if (!TryStringToNumber(value, options, ref number, numfmt, false)) {
+
+ if (!TryStringToNumber(value, options, ref number, numfmt, false))
+ {
//If we failed TryStringToNumber, it may be from one of our special strings.
//Check the three with which we're concerned and rethrow if it's not one of
//those strings.
String sTrim = value.Trim();
- if (sTrim.Equals(numfmt.PositiveInfinitySymbol)) {
+ if (sTrim.Equals(numfmt.PositiveInfinitySymbol))
+ {
return Double.PositiveInfinity;
}
- if (sTrim.Equals(numfmt.NegativeInfinitySymbol)) {
+ if (sTrim.Equals(numfmt.NegativeInfinitySymbol))
+ {
return Double.NegativeInfinity;
}
- if (sTrim.Equals(numfmt.NaNSymbol)) {
+ if (sTrim.Equals(numfmt.NaNSymbol))
+ {
return Double.NaN;
}
- throw new FormatException(Environment.GetResourceString("Format_InvalidString"));
+ throw new FormatException(SR.Format_InvalidString);
}
- if (!NumberBufferToDouble(number.PackForNative(), ref d)) {
- throw new OverflowException(Environment.GetResourceString("Overflow_Double"));
+ if (!NumberBufferToDouble(number.PackForNative(), ref d))
+ {
+ throw new OverflowException(SR.Overflow_Double);
}
return d;
}
- internal unsafe static Int32 ParseInt32(String s, NumberStyles style, NumberFormatInfo info) {
-
- Byte * numberBufferBytes = stackalloc Byte[NumberBuffer.NumberBufferBytes];
+ internal unsafe static Int32 ParseInt32(String s, NumberStyles style, NumberFormatInfo info)
+ {
+ Byte* numberBufferBytes = stackalloc Byte[NumberBuffer.NumberBufferBytes];
NumberBuffer number = new NumberBuffer(numberBufferBytes);
Int32 i = 0;
-
+
StringToNumber(s, style, ref number, info, false);
- if ((style & NumberStyles.AllowHexSpecifier) != 0) {
- if (!HexNumberToInt32(ref number, ref i)) {
- throw new OverflowException(Environment.GetResourceString("Overflow_Int32"));
+ if ((style & NumberStyles.AllowHexSpecifier) != 0)
+ {
+ if (!HexNumberToInt32(ref number, ref i))
+ {
+ throw new OverflowException(SR.Overflow_Int32);
}
}
- else {
- if (!NumberToInt32(ref number, ref i)) {
- throw new OverflowException(Environment.GetResourceString("Overflow_Int32"));
+ else
+ {
+ if (!NumberToInt32(ref number, ref i))
+ {
+ throw new OverflowException(SR.Overflow_Int32);
}
}
- return i;
+ return i;
}
- internal unsafe static Int64 ParseInt64(String value, NumberStyles options, NumberFormatInfo numfmt) {
- Byte * numberBufferBytes = stackalloc Byte[NumberBuffer.NumberBufferBytes];
+ internal unsafe static Int64 ParseInt64(String value, NumberStyles options, NumberFormatInfo numfmt)
+ {
+ Byte* numberBufferBytes = stackalloc Byte[NumberBuffer.NumberBufferBytes];
NumberBuffer number = new NumberBuffer(numberBufferBytes);
Int64 i = 0;
StringToNumber(value, options, ref number, numfmt, false);
- if ((options & NumberStyles.AllowHexSpecifier) != 0) {
- if (!HexNumberToInt64(ref number, ref i)) {
- throw new OverflowException(Environment.GetResourceString("Overflow_Int64"));
+ if ((options & NumberStyles.AllowHexSpecifier) != 0)
+ {
+ if (!HexNumberToInt64(ref number, ref i))
+ {
+ throw new OverflowException(SR.Overflow_Int64);
}
}
- else {
- if (!NumberToInt64(ref number, ref i)) {
- throw new OverflowException(Environment.GetResourceString("Overflow_Int64"));
+ else
+ {
+ if (!NumberToInt64(ref number, ref i))
+ {
+ throw new OverflowException(SR.Overflow_Int64);
}
}
return i;
}
- private unsafe static Boolean ParseNumber(ref char * str, NumberStyles options, ref NumberBuffer number, StringBuilder sb, NumberFormatInfo numfmt, Boolean parseDecimal) {
-
+ private unsafe static Boolean ParseNumber(ref char* str, NumberStyles options, ref NumberBuffer number, StringBuilder sb, NumberFormatInfo numfmt, Boolean parseDecimal)
+ {
const Int32 StateSign = 0x0001;
const Int32 StateParens = 0x0002;
const Int32 StateDigits = 0x0004;
@@ -712,8 +786,9 @@ namespace System {
string groupSep; // group separator from NumberFormatInfo.
string currSymbol = null; // currency symbol from NumberFormatInfo.
- Boolean parsingCurrency = false;
- if ((options & NumberStyles.AllowCurrencySymbol) != 0) {
+ Boolean parsingCurrency = false;
+ if ((options & NumberStyles.AllowCurrencySymbol) != 0)
+ {
currSymbol = numfmt.CurrencySymbol;
// 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.
@@ -722,7 +797,8 @@ namespace System {
groupSep = numfmt.CurrencyGroupSeparator;
parsingCurrency = true;
}
- else {
+ else
+ {
decSep = numfmt.NumberDecimalSeparator;
groupSep = numfmt.NumberGroupSeparator;
}
@@ -730,69 +806,85 @@ namespace System {
Int32 state = 0;
Boolean bigNumber = (sb != null); // When a StringBuilder is provided then we use it in place of the number.digits char[50]
Int32 maxParseDigits = bigNumber ? Int32.MaxValue : NumberMaxDigits;
-
+
char* p = str;
char ch = *p;
char* next;
- while (true) {
+ 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 & 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) {
- state |= StateCurrency;
- currSymbol = 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)
+ {
+ state |= StateCurrency;
+ currSymbol = 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;
Int32 digEnd = 0;
- while (true) {
- if ((ch >= '0' && ch <= '9') || (((options & NumberStyles.AllowHexSpecifier) != 0) && ((ch >= 'a' && ch <= 'f') || (ch >= 'A' && ch <= 'F')))) {
+ while (true)
+ {
+ 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 || (bigNumber && ((options & NumberStyles.AllowHexSpecifier) != 0))) {
- if (digCount < maxParseDigits) {
+ if (ch != '0' || (state & StateNonZero) != 0 || (bigNumber && ((options & NumberStyles.AllowHexSpecifier) != 0)))
+ {
+ if (digCount < maxParseDigits)
+ {
if (bigNumber)
sb.Append(ch);
else
number.digits[digCount++] = ch;
- if (ch != '0' || parseDecimal) {
+ if (ch != '0' || parseDecimal)
+ {
digEnd = digCount;
}
}
- if ((state & StateDecimal) == 0) {
+ if ((state & StateDecimal) == 0)
+ {
number.scale++;
}
state |= StateNonZero;
}
- else if ((state & StateDecimal) != 0) {
+ else if ((state & StateDecimal) != 0)
+ {
number.scale--;
}
}
- else if (((options & NumberStyles.AllowDecimalPoint) != 0) && ((state & StateDecimal) == 0) && ((next = MatchChars(p, decSep)) != null || ((parsingCurrency) && (state & StateCurrency) == 0) && (next = MatchChars(p, numfmt.NumberDecimalSeparator)) != 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, numfmt.NumberGroupSeparator)) != 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 {
+ else
+ {
break;
}
ch = *++p;
@@ -804,64 +896,84 @@ namespace System {
sb.Append('\0');
else
number.digits[digEnd] = '\0';
- if ((state & StateDigits) != 0) {
- if ((ch == 'E' || ch == 'e') && ((options & NumberStyles.AllowExponent) != 0)) {
+ if ((state & StateDigits) != 0)
+ {
+ if ((ch == 'E' || ch == 'e') && ((options & NumberStyles.AllowExponent) != 0))
+ {
char* temp = p;
ch = *++p;
- if ((next = MatchChars(p, numfmt.positiveSign)) != null) {
+ if ((next = MatchChars(p, numfmt.positiveSign)) != null)
+ {
ch = *(p = next);
}
- else if ((next = MatchChars(p, numfmt.negativeSign)) != null) {
+ else if ((next = MatchChars(p, numfmt.negativeSign)) != null)
+ {
ch = *(p = next);
negExp = true;
}
- if (ch >= '0' && ch <= '9') {
+ if (ch >= '0' && ch <= '9')
+ {
Int32 exp = 0;
- do {
+ do
+ {
exp = exp * 10 + (ch - '0');
ch = *++p;
- if (exp > 1000) {
+ if (exp > 1000)
+ {
exp = 9999;
- while (ch >= '0' && ch <= '9') {
+ while (ch >= '0' && ch <= '9')
+ {
ch = *++p;
}
}
} while (ch >= '0' && ch <= '9');
- if (negExp) {
+ if (negExp)
+ {
exp = -exp;
}
number.scale += exp;
}
- else {
+ else
+ {
p = temp;
ch = *p;
}
}
- while (true) {
- 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) {
- currSymbol = null;
- p = next - 1;
- }
- else {
- break;
- }
- }
+ while (true)
+ {
+ 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)
+ {
+ currSymbol = null;
+ p = next - 1;
+ }
+ else
+ {
+ break;
+ }
+ }
ch = *++p;
}
- if ((state & StateParens) == 0) {
- if ((state & StateNonZero) == 0) {
- if (!parseDecimal) {
+ if ((state & StateParens) == 0)
+ {
+ if ((state & StateNonZero) == 0)
+ {
+ if (!parseDecimal)
+ {
number.scale = 0;
}
- if ((state & StateDecimal) == 0) {
+ if ((state & StateDecimal) == 0)
+ {
number.sign = false;
}
}
@@ -873,200 +985,242 @@ namespace System {
return false;
}
- internal unsafe static Single ParseSingle(String value, NumberStyles options, NumberFormatInfo numfmt) {
- if (value == null) {
+ internal unsafe static Single ParseSingle(String value, NumberStyles options, NumberFormatInfo numfmt)
+ {
+ if (value == null)
+ {
throw new ArgumentNullException(nameof(value));
}
- Byte * numberBufferBytes = stackalloc Byte[NumberBuffer.NumberBufferBytes];
+ Byte* numberBufferBytes = stackalloc Byte[NumberBuffer.NumberBufferBytes];
NumberBuffer number = new NumberBuffer(numberBufferBytes);
Double d = 0;
- if (!TryStringToNumber(value, options, ref number, numfmt, false)) {
+ if (!TryStringToNumber(value, options, ref number, numfmt, false))
+ {
//If we failed TryStringToNumber, it may be from one of our special strings.
//Check the three with which we're concerned and rethrow if it's not one of
//those strings.
String sTrim = value.Trim();
- if (sTrim.Equals(numfmt.PositiveInfinitySymbol)) {
+ if (sTrim.Equals(numfmt.PositiveInfinitySymbol))
+ {
return Single.PositiveInfinity;
}
- if (sTrim.Equals(numfmt.NegativeInfinitySymbol)) {
+ if (sTrim.Equals(numfmt.NegativeInfinitySymbol))
+ {
return Single.NegativeInfinity;
}
- if (sTrim.Equals(numfmt.NaNSymbol)) {
+ if (sTrim.Equals(numfmt.NaNSymbol))
+ {
return Single.NaN;
}
- throw new FormatException(Environment.GetResourceString("Format_InvalidString"));
+ throw new FormatException(SR.Format_InvalidString);
}
- if (!NumberBufferToDouble(number.PackForNative(), ref d)) {
- throw new OverflowException(Environment.GetResourceString("Overflow_Single"));
+ if (!NumberBufferToDouble(number.PackForNative(), ref d))
+ {
+ throw new OverflowException(SR.Overflow_Single);
}
Single castSingle = (Single)d;
- if (Single.IsInfinity(castSingle)) {
- throw new OverflowException(Environment.GetResourceString("Overflow_Single"));
+ if (Single.IsInfinity(castSingle))
+ {
+ throw new OverflowException(SR.Overflow_Single);
}
return castSingle;
}
- internal unsafe static UInt32 ParseUInt32(String value, NumberStyles options, NumberFormatInfo numfmt) {
-
- Byte * numberBufferBytes = stackalloc Byte[NumberBuffer.NumberBufferBytes];
+ internal unsafe static UInt32 ParseUInt32(String value, NumberStyles options, NumberFormatInfo numfmt)
+ {
+ Byte* numberBufferBytes = stackalloc Byte[NumberBuffer.NumberBufferBytes];
NumberBuffer number = new NumberBuffer(numberBufferBytes);
UInt32 i = 0;
-
+
StringToNumber(value, options, ref number, numfmt, false);
- if ((options & NumberStyles.AllowHexSpecifier) != 0) {
- if (!HexNumberToUInt32(ref number, ref i)) {
- throw new OverflowException(Environment.GetResourceString("Overflow_UInt32"));
+ if ((options & NumberStyles.AllowHexSpecifier) != 0)
+ {
+ if (!HexNumberToUInt32(ref number, ref i))
+ {
+ throw new OverflowException(SR.Overflow_UInt32);
}
}
- else {
- if (!NumberToUInt32(ref number, ref i)) {
- throw new OverflowException(Environment.GetResourceString("Overflow_UInt32"));
+ else
+ {
+ if (!NumberToUInt32(ref number, ref i))
+ {
+ throw new OverflowException(SR.Overflow_UInt32);
}
}
-
+
return i;
}
- internal unsafe static UInt64 ParseUInt64(String value, NumberStyles options, NumberFormatInfo numfmt) {
- Byte * numberBufferBytes = stackalloc Byte[NumberBuffer.NumberBufferBytes];
+ internal unsafe static UInt64 ParseUInt64(String value, NumberStyles options, NumberFormatInfo numfmt)
+ {
+ Byte* numberBufferBytes = stackalloc Byte[NumberBuffer.NumberBufferBytes];
NumberBuffer number = new NumberBuffer(numberBufferBytes);
UInt64 i = 0;
StringToNumber(value, options, ref number, numfmt, false);
- if ((options & NumberStyles.AllowHexSpecifier) != 0) {
- if (!HexNumberToUInt64(ref number, ref i)) {
- throw new OverflowException(Environment.GetResourceString("Overflow_UInt64"));
+ if ((options & NumberStyles.AllowHexSpecifier) != 0)
+ {
+ if (!HexNumberToUInt64(ref number, ref i))
+ {
+ throw new OverflowException(SR.Overflow_UInt64);
}
}
- else {
- if (!NumberToUInt64(ref number, ref i)) {
- throw new OverflowException(Environment.GetResourceString("Overflow_UInt64"));
+ else
+ {
+ if (!NumberToUInt64(ref number, ref i))
+ {
+ throw new OverflowException(SR.Overflow_UInt64);
}
}
return i;
}
- private unsafe static void StringToNumber(String str, NumberStyles options, ref NumberBuffer number, NumberFormatInfo info, Boolean parseDecimal) {
-
- if (str == null) {
+ private unsafe static void StringToNumber(String str, NumberStyles options, ref NumberBuffer number, NumberFormatInfo info, Boolean parseDecimal)
+ {
+ if (str == null)
+ {
throw new ArgumentNullException(nameof(String));
}
Contract.EndContractBlock();
Debug.Assert(info != null, "");
- fixed (char* stringPointer = str) {
- char * p = stringPointer;
- if (!ParseNumber(ref p, options, ref number, null, info , parseDecimal)
- || (p - stringPointer < str.Length && !TrailingZeros(str, (int)(p - stringPointer)))) {
- throw new FormatException(Environment.GetResourceString("Format_InvalidString"));
+ fixed (char* stringPointer = str)
+ {
+ char* p = stringPointer;
+ if (!ParseNumber(ref p, options, ref number, null, info, parseDecimal)
+ || (p - stringPointer < str.Length && !TrailingZeros(str, (int)(p - stringPointer))))
+ {
+ throw new FormatException(SR.Format_InvalidString);
}
}
}
-
- private static Boolean TrailingZeros(String s, Int32 index) {
+
+ private static Boolean TrailingZeros(String s, Int32 index)
+ {
// For compatibility, we need to allow trailing zeros at the end of a number string
- for (int i = index; i < s.Length; i++) {
- if (s[i] != '\0') {
+ for (int i = index; i < s.Length; i++)
+ {
+ if (s[i] != '\0')
+ {
return false;
}
}
return true;
}
- internal unsafe static Boolean TryParseDecimal(String value, NumberStyles options, NumberFormatInfo numfmt, out Decimal result) {
-
- Byte * numberBufferBytes = stackalloc Byte[NumberBuffer.NumberBufferBytes];
+ internal unsafe static Boolean TryParseDecimal(String value, NumberStyles options, NumberFormatInfo numfmt, out Decimal result)
+ {
+ Byte* numberBufferBytes = stackalloc Byte[NumberBuffer.NumberBufferBytes];
NumberBuffer number = new NumberBuffer(numberBufferBytes);
result = 0;
-
- if (!TryStringToNumber(value, options, ref number, numfmt, true)) {
+
+ if (!TryStringToNumber(value, options, ref number, numfmt, true))
+ {
return false;
}
- if (!NumberBufferToDecimal(number.PackForNative(), ref result)) {
+ if (!NumberBufferToDecimal(number.PackForNative(), ref result))
+ {
return false;
}
return true;
}
- internal unsafe static Boolean TryParseDouble(String value, NumberStyles options, NumberFormatInfo numfmt, out Double result) {
- Byte * numberBufferBytes = stackalloc Byte[NumberBuffer.NumberBufferBytes];
+ internal unsafe static Boolean TryParseDouble(String value, NumberStyles options, NumberFormatInfo numfmt, out Double result)
+ {
+ Byte* numberBufferBytes = stackalloc Byte[NumberBuffer.NumberBufferBytes];
NumberBuffer number = new NumberBuffer(numberBufferBytes);
result = 0;
- if (!TryStringToNumber(value, options, ref number, numfmt, false)) {
+ if (!TryStringToNumber(value, options, ref number, numfmt, false))
+ {
return false;
}
- if (!NumberBufferToDouble(number.PackForNative(), ref result)) {
+ if (!NumberBufferToDouble(number.PackForNative(), ref result))
+ {
return false;
}
return true;
}
- internal unsafe static Boolean TryParseInt32(String s, NumberStyles style, NumberFormatInfo info, out Int32 result) {
-
- Byte * numberBufferBytes = stackalloc Byte[NumberBuffer.NumberBufferBytes];
+ internal unsafe static Boolean TryParseInt32(String s, NumberStyles style, NumberFormatInfo info, out Int32 result)
+ {
+ Byte* numberBufferBytes = stackalloc Byte[NumberBuffer.NumberBufferBytes];
NumberBuffer number = new NumberBuffer(numberBufferBytes);
result = 0;
-
- if (!TryStringToNumber(s, style, ref number, info, false)) {
+
+ if (!TryStringToNumber(s, style, ref number, info, false))
+ {
return false;
}
- if ((style & NumberStyles.AllowHexSpecifier) != 0) {
- if (!HexNumberToInt32(ref number, ref result)) {
+ if ((style & NumberStyles.AllowHexSpecifier) != 0)
+ {
+ if (!HexNumberToInt32(ref number, ref result))
+ {
return false;
}
}
- else {
- if (!NumberToInt32(ref number, ref result)) {
+ else
+ {
+ if (!NumberToInt32(ref number, ref result))
+ {
return false;
}
}
- return true;
+ return true;
}
- internal unsafe static Boolean TryParseInt64(String s, NumberStyles style, NumberFormatInfo info, out Int64 result) {
-
- Byte * numberBufferBytes = stackalloc Byte[NumberBuffer.NumberBufferBytes];
+ internal unsafe static Boolean TryParseInt64(String s, NumberStyles style, NumberFormatInfo info, out Int64 result)
+ {
+ Byte* numberBufferBytes = stackalloc Byte[NumberBuffer.NumberBufferBytes];
NumberBuffer number = new NumberBuffer(numberBufferBytes);
result = 0;
-
- if (!TryStringToNumber(s, style, ref number, info, false)) {
+
+ if (!TryStringToNumber(s, style, ref number, info, false))
+ {
return false;
}
- if ((style & NumberStyles.AllowHexSpecifier) != 0) {
- if (!HexNumberToInt64(ref number, ref result)) {
+ if ((style & NumberStyles.AllowHexSpecifier) != 0)
+ {
+ if (!HexNumberToInt64(ref number, ref result))
+ {
return false;
}
}
- else {
- if (!NumberToInt64(ref number, ref result)) {
+ else
+ {
+ if (!NumberToInt64(ref number, ref result))
+ {
return false;
}
}
- return true;
+ return true;
}
- internal unsafe static Boolean TryParseSingle(String value, NumberStyles options, NumberFormatInfo numfmt, out Single result) {
- Byte * numberBufferBytes = stackalloc Byte[NumberBuffer.NumberBufferBytes];
+ internal unsafe static Boolean TryParseSingle(String value, NumberStyles options, NumberFormatInfo numfmt, out Single result)
+ {
+ Byte* numberBufferBytes = stackalloc Byte[NumberBuffer.NumberBufferBytes];
NumberBuffer number = new NumberBuffer(numberBufferBytes);
result = 0;
Double d = 0;
- if (!TryStringToNumber(value, options, ref number, numfmt, false)) {
+ if (!TryStringToNumber(value, options, ref number, numfmt, false))
+ {
return false;
}
- if (!NumberBufferToDouble(number.PackForNative(), ref d)) {
+ if (!NumberBufferToDouble(number.PackForNative(), ref d))
+ {
return false;
}
Single castSingle = (Single)d;
- if (Single.IsInfinity(castSingle)) {
+ if (Single.IsInfinity(castSingle))
+ {
return false;
}
@@ -1074,68 +1228,82 @@ namespace System {
return true;
}
- internal unsafe static Boolean TryParseUInt32(String s, NumberStyles style, NumberFormatInfo info, out UInt32 result) {
-
- Byte * numberBufferBytes = stackalloc Byte[NumberBuffer.NumberBufferBytes];
+ internal unsafe static Boolean TryParseUInt32(String s, NumberStyles style, NumberFormatInfo info, out UInt32 result)
+ {
+ Byte* numberBufferBytes = stackalloc Byte[NumberBuffer.NumberBufferBytes];
NumberBuffer number = new NumberBuffer(numberBufferBytes);
result = 0;
-
- if (!TryStringToNumber(s, style, ref number, info, false)) {
+
+ if (!TryStringToNumber(s, style, ref number, info, false))
+ {
return false;
}
- if ((style & NumberStyles.AllowHexSpecifier) != 0) {
- if (!HexNumberToUInt32(ref number, ref result)) {
+ if ((style & NumberStyles.AllowHexSpecifier) != 0)
+ {
+ if (!HexNumberToUInt32(ref number, ref result))
+ {
return false;
}
}
- else {
- if (!NumberToUInt32(ref number, ref result)) {
+ else
+ {
+ if (!NumberToUInt32(ref number, ref result))
+ {
return false;
}
}
- return true;
+ return true;
}
- internal unsafe static Boolean TryParseUInt64(String s, NumberStyles style, NumberFormatInfo info, out UInt64 result) {
-
- Byte * numberBufferBytes = stackalloc Byte[NumberBuffer.NumberBufferBytes];
+ internal unsafe static Boolean TryParseUInt64(String s, NumberStyles style, NumberFormatInfo info, out UInt64 result)
+ {
+ Byte* numberBufferBytes = stackalloc Byte[NumberBuffer.NumberBufferBytes];
NumberBuffer number = new NumberBuffer(numberBufferBytes);
result = 0;
-
- if (!TryStringToNumber(s, style, ref number, info, false)) {
+
+ if (!TryStringToNumber(s, style, ref number, info, false))
+ {
return false;
}
- if ((style & NumberStyles.AllowHexSpecifier) != 0) {
- if (!HexNumberToUInt64(ref number, ref result)) {
+ if ((style & NumberStyles.AllowHexSpecifier) != 0)
+ {
+ if (!HexNumberToUInt64(ref number, ref result))
+ {
return false;
}
}
- else {
- if (!NumberToUInt64(ref number, ref result)) {
+ else
+ {
+ if (!NumberToUInt64(ref number, ref result))
+ {
return false;
}
}
- return true;
+ return true;
}
- internal static Boolean TryStringToNumber(String str, NumberStyles options, ref NumberBuffer number, NumberFormatInfo numfmt, Boolean parseDecimal) {
+ internal static Boolean TryStringToNumber(String str, NumberStyles options, ref NumberBuffer number, NumberFormatInfo numfmt, Boolean parseDecimal)
+ {
return TryStringToNumber(str, options, ref number, null, numfmt, parseDecimal);
}
[System.Runtime.CompilerServices.FriendAccessAllowed]
- internal unsafe static Boolean TryStringToNumber(String str, NumberStyles options, ref NumberBuffer number, StringBuilder sb, NumberFormatInfo numfmt, Boolean parseDecimal) {
-
- if (str == null) {
+ internal unsafe static Boolean TryStringToNumber(String str, NumberStyles options, ref NumberBuffer number, StringBuilder sb, NumberFormatInfo numfmt, Boolean parseDecimal)
+ {
+ if (str == null)
+ {
return false;
}
Debug.Assert(numfmt != null, "");
- fixed (char* stringPointer = str) {
- char * p = stringPointer;
- if (!ParseNumber(ref p, options, ref number, sb, numfmt, parseDecimal)
- || (p - stringPointer < str.Length && !TrailingZeros(str, (int)(p - stringPointer)))) {
+ fixed (char* stringPointer = str)
+ {
+ char* p = stringPointer;
+ if (!ParseNumber(ref p, options, ref number, sb, numfmt, parseDecimal)
+ || (p - stringPointer < str.Length && !TrailingZeros(str, (int)(p - stringPointer))))
+ {
return false;
}
}