Merge pull request #601 from knocte/sock_improvements
[mono.git] / mcs / class / corlib / System / UInt32.cs
index 819970e7568bd022de145bd34f5a6681938966be..f78ee9dbab20297f91be7f9e9db1cd9425a01742 100644 (file)
@@ -271,10 +271,9 @@ 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
@@ -285,18 +284,20 @@ namespace System
                                            (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,28 +314,16 @@ 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);
 
@@ -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;
                }