Merge pull request #900 from Blewzman/FixAggregateExceptionGetBaseException
[mono.git] / mcs / class / corlib / System / UInt32.cs
index 819970e7568bd022de145bd34f5a6681938966be..0e88b33012bbfec9c5a6758c131adee29fd494de 100644 (file)
@@ -183,7 +183,7 @@ namespace System
                        NumberFormatInfo nfi = null;
                        if (provider != null) {
                                Type typeNFI = typeof (NumberFormatInfo);
-                               nfi = (NumberFormatInfo) provider.GetFormat (typeNFI);
+                               nfi = provider.GetFormat (typeNFI) as NumberFormatInfo;
                        }
                        if (nfi == null)
                                nfi = Thread.CurrentThread.CurrentCulture.NumberFormat;
@@ -271,32 +271,33 @@ namespace System
 
                        uint number = 0;
                        int nDigits = 0;
-                       bool decimalPointFound = false;
+                       int decimalPointPos = -1;
                        uint digitValue;
                        char hexDigit;
-                       int exponent = 0;
 
                        // Number stuff
                        // Just the same as Int32, but this one adds instead of substract
-                       do {
+                       while (pos < s.Length) {
 
                                if (!Int32.ValidDigit (s [pos], AllowHexSpecifier)) {
                                        if (AllowThousands &&
                                            (Int32.FindOther (ref pos, s, nfi.NumberGroupSeparator)
                                                || Int32.FindOther (ref pos, s, nfi.CurrencyGroupSeparator)))
                                                continue;
-                                       else
-                                               if (!decimalPointFound && AllowDecimalPoint &&
+                                       
+                                       if (AllowDecimalPoint && decimalPointPos < 0 &&
                                            (Int32.FindOther (ref pos, s, nfi.NumberDecimalSeparator)
                                                || Int32.FindOther (ref pos, s, nfi.CurrencyDecimalSeparator))) {
-                                                       decimalPointFound = true;
+                                                       decimalPointPos = nDigits;
                                                        continue;
                                                }
 
                                        break;
                                }
+
+                               nDigits++;
+
                                if (AllowHexSpecifier) {
-                                       nDigits++;
                                        hexDigit = s [pos++];
                                        if (Char.IsDigit (hexDigit))
                                                digitValue = (uint) (hexDigit - '0');
@@ -313,30 +314,18 @@ namespace System
                                                number = (uint) l;
                                        } else
                                                number = checked (number * 16 + digitValue);
+
+                                       continue;
                                }
-                               else if (decimalPointFound) {
-                                       nDigits++;
-                                       // Allows decimal point as long as it's only 
-                                       // followed by zeroes.
-                                       if (s [pos++] != '0') {
-                                               if (!tryParse)
-                                                       exc = new OverflowException (Locale.GetText ("Value too large or too small."));
-                                               return false;
-                                       }
-                               }
-                               else {
-                                       nDigits++;
 
-                                       try {
-                                               number = checked (number * 10 + (uint) (s [pos++] - '0'));
-                                       }
-                                       catch (OverflowException) {
-                                               if (!tryParse)
-                                                       exc = new OverflowException (Locale.GetText ("Value too large or too small."));
-                                               return false;
-                                       }
+                               try {
+                                       number = checked (number * 10 + (uint) (s [pos++] - '0'));
+                               } catch (OverflowException) {
+                                       if (!tryParse)
+                                               exc = new OverflowException (Locale.GetText ("Value too large or too small."));
+                                       return false;
                                }
-                       } while (pos < s.Length);
+                       }
 
                        // Post number stuff
                        if (nDigits == 0) {
@@ -345,6 +334,7 @@ namespace System
                                return false;
                        }
 
+                       int exponent = 0;
                        if (AllowExponent)
                                if (Int32.FindExponent (ref pos, s, ref exponent, tryParse, ref exc) && exc != null)
                                        return false;
@@ -400,21 +390,37 @@ namespace System
                                return false;
                        }
 
-                       // result *= 10^exponent
-                       if (exponent > 0) {
+                       if (decimalPointPos >= 0)
+                               exponent = exponent - nDigits + decimalPointPos;
+                       
+                       if (exponent < 0) {
+                               //
+                               // Any non-zero values after decimal point are not allowed
+                               //
+                               long remainder;
+                               number = (uint) Math.DivRem (number, (int) Math.Pow (10, -exponent), out remainder);
+                               if (remainder != 0) {
+                                       if (!tryParse)
+                                               exc = new OverflowException ("Value too large or too small.");
+                                       return false;
+                               }
+                       } else if (exponent > 0) {
+                               //
+                               // result *= 10^exponent
+                               //
                                // Reduce the risk of throwing an overflow exc
+                               //
                                double res = checked (Math.Pow (10, exponent) * number);
-                               if (res < Int32.MinValue || res > Int32.MaxValue) {
+                               if (res < MinValue || res > MaxValue) {
                                        if (!tryParse)
                                                exc = new OverflowException ("Value too large or too small.");
                                        return false;
                                }
 
-                               number = (uint) res;
+                               number = (uint)res;
                        }
 
                        result = number;
-
                        return true;
                }