X-Git-Url: http://wien.tomnetworks.com/gitweb/?a=blobdiff_plain;f=mcs%2Fclass%2Fcorlib%2FSystem%2FUInt32.cs;h=f78ee9dbab20297f91be7f9e9db1cd9425a01742;hb=60979ce4a41d1be8f9d3d4d38162c0803207b4d5;hp=761c875f3d0546f943aded3534de0ae1729f1ff9;hpb=06f32065de44ab091d41f3e79da50ad761f7b71f;p=mono.git diff --git a/mcs/class/corlib/System/UInt32.cs b/mcs/class/corlib/System/UInt32.cs index 761c875f3d0..f78ee9dbab2 100644 --- a/mcs/class/corlib/System/UInt32.cs +++ b/mcs/class/corlib/System/UInt32.cs @@ -1,11 +1,13 @@ // // System.UInt32.cs // -// Author: +// Authors: // Miguel de Icaza (miguel@ximian.com) +// Marek Safar (marek.safar@gmail.com) // // (C) Ximian, Inc. http://www.ximian.com // Copyright (C) 2004 Novell (http://www.novell.com) +// Copyright (C) 2012 Xamarin Inc (http://www.xamarin.com) // // Permission is hereby granted, free of charge, to any person obtaining // a copy of this software and associated documentation files (the @@ -34,13 +36,8 @@ namespace System { [Serializable] [CLSCompliant (false)] -#if NET_2_0 [System.Runtime.InteropServices.ComVisible (true)] -#endif - public struct UInt32 : IFormattable, IConvertible, IComparable -#if NET_2_0 - , IComparable, IEquatable -#endif + public struct UInt32 : IFormattable, IConvertible, IComparable, IComparable, IEquatable { public const uint MaxValue = 0xffffffff; public const uint MinValue = 0; @@ -55,13 +52,12 @@ namespace System if (!(value is System.UInt32)) throw new ArgumentException (Locale.GetText ("Value is not a System.UInt32.")); - if (this.m_value == (uint) value) - return 0; + uint val = (uint) value; - if (this.m_value < (uint) value) - return -1; + if (m_value == val) + return 0; - return 1; + return (m_value < val) ? -1 : 1; } public override bool Equals (object obj) @@ -77,7 +73,6 @@ namespace System return (int) m_value; } -#if NET_2_0 public int CompareTo (uint value) { if (m_value == value) @@ -88,11 +83,10 @@ namespace System return -1; } - public bool Equals (uint value) + public bool Equals (uint obj) { - return value == m_value; + return obj == m_value; } -#endif internal static bool Parse (string s, bool tryParse, out uint result, out Exception exc) { @@ -140,24 +134,15 @@ namespace System if (c >= '0' && c <= '9') { uint d = (uint) (c - '0'); - val = checked (val * 10 + d); - digits_seen = true; - } - else { - if (Char.IsWhiteSpace (c)) { - for (i++; i < len; i++) { - if (!Char.IsWhiteSpace (s [i])) { - if (!tryParse) - exc = Int32.GetFormatException (); - return false; - } - } - break; - } else { + if ((val > MaxValue/10) || (val == (MaxValue / 10) && d > (MaxValue % 10))){ if (!tryParse) - exc = Int32.GetFormatException (); + exc = new OverflowException (Locale.GetText ("Value is too large")); return false; } + val = (val * 10) + d; + digits_seen = true; + } else if (!Int32.ProcessTrailingWhitespace (tryParse, s, i, ref exc)){ + return false; } } if (!digits_seen) { @@ -195,12 +180,12 @@ namespace System return false; } - NumberFormatInfo nfi; + NumberFormatInfo nfi = null; if (provider != null) { Type typeNFI = typeof (NumberFormatInfo); nfi = (NumberFormatInfo) provider.GetFormat (typeNFI); } - else + if (nfi == null) nfi = Thread.CurrentThread.CurrentCulture.NumberFormat; if (!Int32.CheckStyle (style, tryParse, ref exc)) @@ -215,6 +200,7 @@ namespace System bool AllowLeadingSign = (style & NumberStyles.AllowLeadingSign) != 0; bool AllowTrailingWhite = (style & NumberStyles.AllowTrailingWhite) != 0; bool AllowLeadingWhite = (style & NumberStyles.AllowLeadingWhite) != 0; + bool AllowExponent = (style & NumberStyles.AllowExponent) != 0; int pos = 0; @@ -241,6 +227,7 @@ namespace System exc = Int32.GetFormatException (); return false; } + if (s.Substring (pos, nfi.PositiveSign.Length) == nfi.PositiveSign) { if (!tryParse) exc = Int32.GetFormatException (); @@ -255,7 +242,8 @@ namespace System if (AllowLeadingWhite && !Int32.JumpOverWhite (ref pos, s, true, tryParse, ref exc)) return false; if (AllowCurrencySymbol) { - Int32.FindCurrency (ref pos, s, nfi, ref foundCurrency); + Int32.FindCurrency (ref pos, s, nfi, + ref foundCurrency); if (foundCurrency && AllowLeadingWhite && !Int32.JumpOverWhite (ref pos, s, true, tryParse, ref exc)) return false; @@ -271,7 +259,8 @@ namespace System return false; if (foundCurrency) { if (!foundSign && AllowLeadingSign) { - Int32.FindSign (ref pos, s, nfi, ref foundSign, ref negative); + Int32.FindSign (ref pos, s, nfi, ref foundSign, + ref negative); if (foundSign && AllowLeadingWhite && !Int32.JumpOverWhite (ref pos, s, true, tryParse, ref exc)) return false; @@ -282,7 +271,7 @@ namespace System uint number = 0; int nDigits = 0; - bool decimalPointFound = false; + int decimalPointPos = -1; uint digitValue; char hexDigit; @@ -291,18 +280,24 @@ namespace System do { if (!Int32.ValidDigit (s [pos], AllowHexSpecifier)) { - if (AllowThousands && Int32.FindOther (ref pos, s, nfi.NumberGroupSeparator)) + if (AllowThousands && + (Int32.FindOther (ref pos, s, nfi.NumberGroupSeparator) + || Int32.FindOther (ref pos, s, nfi.CurrencyGroupSeparator))) continue; - else - if (!decimalPointFound && AllowDecimalPoint && - Int32.FindOther (ref pos, s, nfi.NumberDecimalSeparator)) { - decimalPointFound = true; + + if (AllowDecimalPoint && decimalPointPos < 0 && + (Int32.FindOther (ref pos, s, nfi.NumberDecimalSeparator) + || Int32.FindOther (ref pos, s, nfi.CurrencyDecimalSeparator))) { + decimalPointPos = nDigits; continue; } + break; } - else if (AllowHexSpecifier) { - nDigits++; + + nDigits++; + + if (AllowHexSpecifier) { hexDigit = s [pos++]; if (Char.IsDigit (hexDigit)) digitValue = (uint) (hexDigit - '0'); @@ -311,29 +306,24 @@ namespace System else digitValue = (uint) (hexDigit - 'A' + 10); - number = checked (number * 16 + digitValue); - } - 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; - } + if (tryParse){ + ulong l = number * 16 + digitValue; + + if (l > MaxValue) + return false; + number = (uint) l; + } else + number = checked (number * 16 + digitValue); + + continue; } - 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); @@ -344,25 +334,32 @@ namespace System return false; } + int exponent = 0; + if (AllowExponent) + if (Int32.FindExponent (ref pos, s, ref exponent, tryParse, ref exc) && exc != null) + return false; + if (AllowTrailingSign && !foundSign) { // Sign + Currency Int32.FindSign (ref pos, s, nfi, ref foundSign, ref negative); - if (foundSign) { + if (foundSign && pos < s.Length) { if (AllowTrailingWhite && !Int32.JumpOverWhite (ref pos, s, true, tryParse, ref exc)) return false; - if (AllowCurrencySymbol) - Int32. FindCurrency (ref pos, s, nfi, ref foundCurrency); } } if (AllowCurrencySymbol && !foundCurrency) { + if (AllowTrailingWhite && pos < s.Length && !Int32.JumpOverWhite (ref pos, s, false, tryParse, ref exc)) + return false; + // Currency + sign Int32.FindCurrency (ref pos, s, nfi, ref foundCurrency); - if (foundCurrency) { + if (foundCurrency && pos < s.Length) { if (AllowTrailingWhite && !Int32.JumpOverWhite (ref pos, s, true, tryParse, ref exc)) return false; if (!foundSign && AllowTrailingSign) - Int32.FindSign (ref pos, s, nfi, ref foundSign, ref negative); + Int32.FindSign (ref pos, s, nfi, ref foundSign, + ref negative); } } @@ -393,8 +390,37 @@ namespace System return false; } - result = number; + 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 < MinValue || res > MaxValue) { + if (!tryParse) + exc = new OverflowException ("Value too large or too small."); + return false; + } + number = (uint)res; + } + + result = number; return true; } @@ -411,12 +437,12 @@ namespace System } [CLSCompliant (false)] - public static uint Parse (string s, NumberStyles style, IFormatProvider fp) + public static uint Parse (string s, NumberStyles style, IFormatProvider provider) { Exception exc; uint res; - if (!Parse (s, style, fp, false, out res, out exc)) + if (!Parse (s, style, provider, false, out res, out exc)) throw exc; return res; @@ -434,7 +460,6 @@ namespace System return Parse (s, style, null); } -#if NET_2_0 [CLSCompliant (false)] public static bool TryParse (string s, out uint result) { @@ -458,16 +483,15 @@ namespace System return true; } -#endif public override string ToString () { - return NumberFormatter.FormatGeneral (new NumberFormatter.NumberStore (m_value)); + return NumberFormatter.NumberToString (m_value, null); } - public string ToString (IFormatProvider fp) + public string ToString (IFormatProvider provider) { - return NumberFormatter.FormatGeneral (new NumberFormatter.NumberStore (m_value), fp); + return NumberFormatter.NumberToString (m_value, provider); } public string ToString (string format) @@ -475,10 +499,9 @@ namespace System return ToString (format, null); } - public string ToString (string format, IFormatProvider fp) + public string ToString (string format, IFormatProvider provider) { - NumberFormatInfo nfi = NumberFormatInfo.GetInstance (fp); - return NumberFormatter.NumberToString (format, m_value, nfi); + return NumberFormatter.NumberToString (format, m_value, provider); } // =========== IConvertible Methods =========== // @@ -542,9 +565,11 @@ namespace System return System.Convert.ToSingle (m_value); } - object IConvertible.ToType (Type conversionType, IFormatProvider provider) + object IConvertible.ToType (Type targetType, IFormatProvider provider) { - return System.Convert.ToType (m_value, conversionType, provider); + if (targetType == null) + throw new ArgumentNullException ("targetType"); + return System.Convert.ToType (m_value, targetType, provider, false); } ushort IConvertible.ToUInt16 (IFormatProvider provider)