Redesign System/NumberFormatter to improve primitive numeric types ToString performance.
[mono.git] / mcs / class / corlib / System.Globalization / NumberFormatInfo.cs
index 169ad6c2f9eb7241b850ca2ff128a1eefed8acc2..f24a20fb0c9908082439739271797815a13eece4 100644 (file)
 // Other than that this is totally ECMA compliant.
 //
 
+using System.Runtime.InteropServices;
+
 namespace System.Globalization {
 
+#if NET_2_0
+       [ComVisible (true)]
+#endif
        [Serializable]
        public sealed class NumberFormatInfo : ICloneable, IFormatProvider {
                private bool isReadOnly;
@@ -95,9 +100,17 @@ namespace System.Globalization {
                bool m_useUserOverride; // Unused, but MS.NET serializes this.
                bool validForParseAsNumber; // Unused, but MS.NET serializes this.
                bool validForParseAsCurrency; // Unused, but MS.NET serializes this.
+#if NET_2_0
+               string[] nativeDigits = invariantNativeDigits;
+               int digitSubstitution = 1; // DigitShapes.None.
+
+               static string [] invariantNativeDigits = new string [] {"0", "1", "2", "3", "4", "5", "6", "7", "8", "9"};
+#endif
 
-               internal NumberFormatInfo (int lcid)
+               internal NumberFormatInfo (int lcid, bool read_only)
                {
+                       isReadOnly = read_only;
+
                        //FIXME: should add more LCID
                        // CultureInfo uses this one also.
                        if (lcid != 0x007F)
@@ -144,11 +157,15 @@ namespace System.Globalization {
                                break;
                        }
                }
+
+               internal NumberFormatInfo (bool read_only) : this (0x007f, read_only)
+               {
+               }
                
-               public NumberFormatInfo () : this (0x007f)
+               public NumberFormatInfo () : this (false)
                {
                }
-                               
+
                // this is called by mono/mono/metadata/locales.c
                void InitPatterns ()
                {
@@ -378,11 +395,21 @@ namespace System.Globalization {
 
                public int[] CurrencyGroupSizes {
                        get {
-                               return (int []) currencyGroupSizes.Clone ();
+                               return (int []) RawCurrencyGroupSizes.Clone ();
+                       }
+                       
+                       set {
+                               RawCurrencyGroupSizes = value;
+                       }
+               }
+
+               internal int[] RawCurrencyGroupSizes {
+                       get {
+                               return currencyGroupSizes;
                        }
                        
                        set {
-                               if (value == null || value.Length == 0
+                               if (value == null) 
                                        throw new ArgumentNullException
                                        ("The value specified for the property is a null reference");
                                
@@ -390,6 +417,11 @@ namespace System.Globalization {
                                        throw new InvalidOperationException
                                        ("The current instance is read-only and a set operation was attempted");
                                
+                               if (value.Length == 0) {
+                                       currencyGroupSizes = new int [0];
+                                       return;
+                               }
+                               
                                // All elements except last need to be in range 1 - 9, last can be 0.
                                int last = value.Length - 1;
 
@@ -508,6 +540,31 @@ namespace System.Globalization {
                        }
                }
                
+#if NET_2_0
+               [MonoNotSupported ("We don't have native digit info")]
+               [ComVisible (false)]
+               public string [] NativeDigits {
+                       get { return nativeDigits; }
+                       set {
+                               if (value == null)
+                                       throw new ArgumentNullException ("value");
+                               if (value.Length != 10)
+                                       throw new ArgumentException ("Argument array length must be 10");
+                               foreach (string s in value)
+                                       if (String.IsNullOrEmpty (s))
+                                               throw new ArgumentException ("Argument array contains one or more null strings");
+                               nativeDigits = value;
+                       }
+               }
+
+               [MonoNotSupported ("We don't have native digit info")]
+               [ComVisible (false)]
+               public DigitShapes DigitSubstitution {
+                       get { return (DigitShapes) digitSubstitution; }
+                       set { digitSubstitution = (int) value; }
+               }
+#endif
+               
                public string NegativeInfinitySymbol {
                        get {
                                return negativeInfinitySymbol;
@@ -603,11 +660,21 @@ namespace System.Globalization {
 
                public int[] NumberGroupSizes {
                        get {
-                               return (int []) numberGroupSizes.Clone ();
+                               return (int []) RawNumberGroupSizes.Clone ();
                        }
                        
                        set {
-                               if (value == null || value.Length == 0) 
+                               RawNumberGroupSizes = value;
+                       }
+               }
+
+               internal int[] RawNumberGroupSizes {
+                       get {
+                               return numberGroupSizes;
+                       }
+                       
+                       set {
+                               if (value == null) 
                                        throw new ArgumentNullException
                                        ("The value specified for the property is a null reference");
                                
@@ -615,6 +682,10 @@ namespace System.Globalization {
                                        throw new InvalidOperationException
                                        ("The current instance is read-only and a set operation was attempted");
                                
+                               if (value.Length == 0) {
+                                       numberGroupSizes = new int [0];
+                                       return;
+                               }
                                // All elements except last need to be in range 1 - 9, last can be 0.
                                int last = value.Length - 1;
 
@@ -709,11 +780,21 @@ namespace System.Globalization {
 
                public int[] PercentGroupSizes {
                        get {
-                               return (int []) percentGroupSizes.Clone ();
+                               return (int []) RawPercentGroupSizes.Clone ();
                        }
                        
                        set {
-                               if (value == null || value.Length == 0) 
+                               RawPercentGroupSizes = value;
+                       }
+               }
+
+               internal int[] RawPercentGroupSizes {
+                       get {
+                               return percentGroupSizes;
+                       }
+                       
+                       set {
+                               if (value == null) 
                                        throw new ArgumentNullException
                                        ("The value specified for the property is a null reference");
                                
@@ -721,8 +802,14 @@ namespace System.Globalization {
                                        throw new InvalidOperationException
                                        ("The current instance is read-only and a set operation was attempted");
                                
-if (this == CultureInfo.CurrentCulture.NumberFormat)
-throw new Exception ("HERE the value was modified");
+                               if (this == CultureInfo.CurrentCulture.NumberFormat)
+                                       throw new Exception ("HERE the value was modified");
+                               
+                               if (value.Length == 0) {
+                                       percentGroupSizes = new int [0];
+                                       return;
+                               }
+
                                // All elements except last need to be in range 1 - 9, last can be 0.
                                int last = value.Length - 1;