remove warning
[mono.git] / mcs / class / corlib / System / Double.cs
index 7cfbab954130ac2fff42cd4d4b0d35c174f91fd0..23198122acc40039ff119af139ebb7f3cfd0b7da 100644 (file)
@@ -42,9 +42,12 @@ using System.Runtime.ConstrainedExecution;
 namespace System {
        
        [Serializable]
+#if NET_2_0
+       [System.Runtime.InteropServices.ComVisible (true)]
+#endif
        public struct Double : IComparable, IFormattable, IConvertible
 #if NET_2_0
-               , IComparable <double>
+               , IComparable <double>, IEquatable <double>
 #endif
        {
                public const double Epsilon = 4.9406564584124650e-324;
@@ -56,9 +59,6 @@ namespace System {
                
                internal double m_value;
 
-               [MethodImplAttribute(MethodImplOptions.InternalCall)]
-               extern internal static void AssertEndianity (out double value);
-
                public int CompareTo (object v)
                {
                        if (v == null)
@@ -162,7 +162,9 @@ namespace System {
 #endif
                public static bool IsNaN (double d)
                {
+#pragma warning disable 1718
                        return (d != d);
+#pragma warning restore
                }
 
                public static bool IsNegativeInfinity (double d)
@@ -198,20 +200,63 @@ namespace System {
                private const int State_ExponentSign = 4;
                private const int State_Exponent = 5;
                private const int State_ConsumeWhiteSpace = 6;
+               private const int State_Exit = 7;
                
-               [MonoTODO("check if digits are group in correct numbers between the group separators")]
                public static double Parse (string s, NumberStyles style, IFormatProvider provider)
                {
-                       if (s == null) throw new ArgumentNullException();
-                       if (style > NumberStyles.Any)
-                       {
-                               throw new ArgumentException();
+                       Exception exc;
+                       double result;
+                       
+                       if (!Parse (s, style, provider, false, out result, out exc))
+                               throw exc;
+
+                       return result;
+               }
+               
+               // FIXME: check if digits are group in correct numbers between the group separators
+               internal static bool Parse (string s, NumberStyles style, IFormatProvider provider, bool tryParse, out double result, out Exception exc)
+               {
+                       result = 0;
+                       exc = null;
+                       
+                       if (s == null) {
+                               if (!tryParse)
+                                       exc = new ArgumentNullException ("s");
+                               return false;
+                       }
+                       if (s.Length == 0) {
+                               if (!tryParse)
+                                       exc = new FormatException ();
+                               return false;
+                       }
+#if NET_2_0
+                       // yes it's counter intuitive (buggy?) but even TryParse actually throws in this case
+                       if ((style & NumberStyles.AllowHexSpecifier) != 0) {
+                               string msg = Locale.GetText ("Double doesn't support parsing with '{0}'.", "AllowHexSpecifier");
+                               throw new ArgumentException (msg);
                        }
+#endif
+                       if (style > NumberStyles.Any) {
+                               if (!tryParse)
+                                       exc = new ArgumentException();
+                               return false;
+                       }
+
                        NumberFormatInfo format = NumberFormatInfo.GetInstance(provider);
                        if (format == null) throw new Exception("How did this happen?");
-                       if (s == format.NaNSymbol) return Double.NaN;
-                       if (s == format.PositiveInfinitySymbol) return Double.PositiveInfinity;
-                       if (s == format.NegativeInfinitySymbol) return Double.NegativeInfinity;
+                       
+                       if (s == format.NaNSymbol) {
+                               result = Double.NaN;
+                               return true;
+                       }
+                       if (s == format.PositiveInfinitySymbol) {
+                               result = Double.PositiveInfinity;
+                               return true;
+                       }
+                       if (s == format.NegativeInfinitySymbol) {
+                               result = Double.NegativeInfinity;
+                               return true;
+                       }
 
                        //
                        // validate and prepare string for C
@@ -226,8 +271,11 @@ namespace System {
                                while (sidx < len && Char.IsWhiteSpace (c = s [sidx]))
                                       sidx++;
 
-                               if (sidx == len)
-                                       throw new FormatException();
+                               if (sidx == len) {
+                                       if (!tryParse)
+                                               exc = Int32.GetFormatException ();
+                                       return false;
+                               }
                        }
 
                        bool allow_trailing_white = ((style & NumberStyles.AllowTrailingWhite) != 0);
@@ -242,8 +290,10 @@ namespace System {
                        //
                        string decimal_separator = null;
                        string group_separator = null;
+                       string currency_symbol = null;
                        int decimal_separator_len = 0;
                        int group_separator_len = 0;
+                       int currency_symbol_len = 0;
                        if ((style & NumberStyles.AllowDecimalPoint) != 0){
                                decimal_separator = format.NumberDecimalSeparator;
                                decimal_separator_len = decimal_separator.Length;
@@ -252,6 +302,10 @@ namespace System {
                                group_separator = format.NumberGroupSeparator;
                                group_separator_len = group_separator.Length;
                        }
+                       if ((style & NumberStyles.AllowCurrencySymbol) != 0){
+                               currency_symbol = format.CurrencySymbol;
+                               currency_symbol_len = currency_symbol.Length;
+                       }
                        string positive = format.PositiveSign;
                        string negative = format.NegativeSign;
                        
@@ -262,6 +316,7 @@ namespace System {
                                        sidx = len;
                                        continue;
                                }
+
                                switch (state){
                                case State_AllowSign:
                                        if ((style & NumberStyles.AllowLeadingSign) != 0){
@@ -292,9 +347,8 @@ namespace System {
                                                goto case State_Decimal;
                                        
                                        if (decimal_separator != null &&
-                                           decimal_separator [0] == c){
-                                               if (s.Substring (sidx, decimal_separator_len) ==
-                                                   decimal_separator){
+                                           decimal_separator [0] == c) {
+                                               if (String.CompareOrdinal (s, sidx, decimal_separator, 0, decimal_separator_len) == 0) {
                                                        b [didx++] = (byte) '.';
                                                        sidx += decimal_separator_len-1;
                                                        state = State_Decimal; 
@@ -310,11 +364,22 @@ namespace System {
                                                        break;
                                                }
                                        }
+                                       if (currency_symbol != null &&
+                                           currency_symbol [0] == c){
+                                               if (s.Substring (sidx, currency_symbol_len) ==
+                                                   currency_symbol){
+                                                       sidx += currency_symbol_len-1;
+                                                       state = State_Digits; 
+                                                       break;
+                                               }
+                                       }
                                        
                                        if (Char.IsWhiteSpace (c))
                                                goto case State_ConsumeWhiteSpace;
 
-                                       throw new FormatException ("Unknown char: " + c);
+                                       if (!tryParse)
+                                               exc = new FormatException ("Unknown char: " + c);
+                                       return false;
 
                                case State_Decimal:
                                        if (Char.IsDigit (c)){
@@ -323,8 +388,11 @@ namespace System {
                                        }
 
                                        if (c == 'e' || c == 'E'){
-                                               if ((style & NumberStyles.AllowExponent) == 0)
-                                                       throw new FormatException ("Unknown char: " + c);
+                                               if ((style & NumberStyles.AllowExponent) == 0) {
+                                                       if (!tryParse)
+                                                               exc = new FormatException ("Unknown char: " + c);
+                                                       return false;
+                                               }
                                                b [didx++] = (byte) c;
                                                state = State_ExponentSign;
                                                break;
@@ -332,7 +400,10 @@ namespace System {
                                        
                                        if (Char.IsWhiteSpace (c))
                                                goto case State_ConsumeWhiteSpace;
-                                       throw new FormatException ("Unknown char: " + c);
+                                       
+                                       if (!tryParse)
+                                               exc = new FormatException ("Unknown char: " + c);
+                                       return false;
 
                                case State_ExponentSign:
                                        if (Char.IsDigit (c)){
@@ -358,8 +429,10 @@ namespace System {
                                        if (Char.IsWhiteSpace (c))
                                                goto case State_ConsumeWhiteSpace;
                                        
-                                       throw new FormatException ("Unknown char: " + c);
-
+                                       if (!tryParse)
+                                               exc = new FormatException ("Unknown char: " + c);
+                                       return false;
+                                       
                                case State_Exponent:
                                        if (Char.IsDigit (c)){
                                                b [didx++] = (byte) c;
@@ -368,44 +441,69 @@ namespace System {
                                        
                                        if (Char.IsWhiteSpace (c))
                                                goto case State_ConsumeWhiteSpace;
-                                       throw new FormatException ("Unknown char: " + c);
+                                       
+                                       if (!tryParse)
+                                               exc = new FormatException ("Unknown char: " + c);
+                                       return false;
 
                                case State_ConsumeWhiteSpace:
-                                       if (allow_trailing_white && Char.IsWhiteSpace (c))
+                                       if (allow_trailing_white && Char.IsWhiteSpace (c)) {
+                                               state = State_ConsumeWhiteSpace;
                                                break;
-                                       throw new FormatException ("Unknown char");
+                                       }
+                                       
+                                       if (!tryParse)
+                                               exc = new FormatException ("Unknown char");
+                                       return false;
                                }
+
+                               if (state == State_Exit)
+                                       break;
                        }
 
                        b [didx] = 0;
                        unsafe {
                                fixed (byte *p = &b [0]){
-                                       double retVal = ParseImpl (p);
-                                       if (IsPositiveInfinity(retVal) || IsNegativeInfinity(retVal))
-                                               throw new OverflowException();
+                                       double retVal;
+                                       if (!ParseImpl (p, out retVal)) {
+                                               if (!tryParse)
+                                                       exc = Int32.GetFormatException ();
+                                               return false;
+                                       }
+                                       if (IsPositiveInfinity(retVal) || IsNegativeInfinity(retVal)) {
+                                               if (!tryParse)
+                                                       exc = new OverflowException ();
+                                               return false;
+                                       }
 
-                                       return retVal;
+                                       result = retVal;
+                                       return true;
                                }
                        }
                }
 
                [MethodImplAttribute(MethodImplOptions.InternalCall)]
-               unsafe private static extern double ParseImpl (byte *byte_ptr);
+               unsafe private static extern bool ParseImpl (byte *byte_ptr, out double value);
                
                public static bool TryParse (string s,
                                             NumberStyles style,
                                             IFormatProvider provider,
                                             out double result)
                {
-                       try {
-                               result = Parse (s, style, provider);
-                               return true;
-                       } catch {
+                       Exception exc;
+                       if (!Parse (s, style, provider, true, out result, out exc)) {
                                result = 0;
                                return false;
                        }
-               }
 
+                       return true;
+               }
+#if NET_2_0
+               public static bool TryParse (string s, out double result)
+               {
+                       return TryParse (s, NumberStyles.Any, null, out result);
+               }
+#endif
                public override string ToString ()
                {
                        return ToString (null, null);