Redesign System/NumberFormatter to improve primitive numeric types ToString performance.
[mono.git] / mcs / class / corlib / System.Globalization / NumberFormatInfo.cs
index 160cbc875dbdeb0c948fb937c4b21bc1544e14f0..f24a20fb0c9908082439739271797815a13eece4 100644 (file)
@@ -4,9 +4,34 @@
 // Author:
 //   Derek Holden (dholden@draper.com)
 //   Bob Smith    (bob@thestuff.net)
+//   Mohammad DAMT (mdamt@cdl2000.com)
 //
 // (C) Derek Holden
 // (C) Bob Smith     http://www.thestuff.net
+// (c) 2003, PT Cakram Datalingga Duaribu   http://www.cdl2000.com
+//
+
+//
+// Copyright (C) 2004 Novell, Inc (http://www.novell.com)
+//
+// Permission is hereby granted, free of charge, to any person obtaining
+// a copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+// 
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+// 
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 //
 
 //
 // 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 readOnly;
+               private bool isReadOnly;
+               // used for temporary storage. Used in InitPatterns ()
+               string decimalFormats;
+               string currencyFormats;
+               string percentFormats;
+               string digitPattern = "#";
+               string zeroPattern = "0";
                
                // Currency Related Format Info
                private int currencyDecimalDigits;
@@ -35,7 +71,7 @@ namespace System.Globalization {
                private int currencyPositivePattern;
                private string currencySymbol;
 
-               private string naNSymbol;
+               private string nanSymbol;
                private string negativeInfinitySymbol;
                private string negativeSign;
 
@@ -58,9 +94,23 @@ namespace System.Globalization {
                private string perMilleSymbol;
                private string positiveInfinitySymbol;
                private string positiveSign;
-
-               internal NumberFormatInfo (int lcid)
+               
+               string ansiCurrencySymbol;      // TODO, MS.NET serializes this.
+               int m_dataItem; // Unused, but MS.NET serializes this.
+               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, bool read_only)
                {
+                       isReadOnly = read_only;
+
                        //FIXME: should add more LCID
                        // CultureInfo uses this one also.
                        if (lcid != 0x007F)
@@ -70,7 +120,7 @@ namespace System.Globalization {
 
                                // The Invariant Culture Info ID.
                        case 0x007f:
-                               readOnly = false;
+                               isReadOnly = false;
                                
                                // Currency Related Format Info
                                currencyDecimalDigits =       2;
@@ -81,7 +131,7 @@ namespace System.Globalization {
                                currencyPositivePattern =     0;
                                currencySymbol =              "$";
                                
-                               naNSymbol =                   "NaN";
+                               nanSymbol =                   "NaN";
                                negativeInfinitySymbol =      "-Infinity";
                                negativeSign =                "-";
                                
@@ -90,7 +140,7 @@ namespace System.Globalization {
                                numberDecimalSeparator =      ".";
                                numberGroupSeparator =        ",";
                                numberGroupSizes =            new int[1] { 3 };
-                               numberNegativePattern =       0;
+                               numberNegativePattern =       1;
                                
                                // Percent Related Format Info
                                percentDecimalDigits =        2;
@@ -107,11 +157,185 @@ 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 ()
+               {
+                       string [] partOne, partTwo;
+                       string [] posNeg = decimalFormats.Split (new char [1] {';'}, 2);
+                       
+                       if (posNeg.Length == 2) {
+                               
+                               partOne = posNeg [0].Split (new char [1] {'.'}, 2);
+                                                                                       
+                               if (partOne.Length == 2) {
+                                       // assumed same for both positive and negative
+                                       // decimal digit side
+                                       numberDecimalDigits = 0;                                        
+                                       for (int i = 0; i < partOne [1].Length; i ++) {                                         
+                                               if (partOne [1][i] == digitPattern [0]) {
+                                                       numberDecimalDigits ++;                                                 
+                                               } else
+                                                       break;                                          
+                                       }
+
+                                       // decimal grouping side
+                                       partTwo = partOne [0].Split (',');
+                                       if (partTwo.Length > 1) {
+                                               numberGroupSizes = new int [partTwo.Length - 1];
+                                               for (int i = 0; i < numberGroupSizes.Length; i ++) {
+                                                       string pat = partTwo [i + 1];
+                                                       numberGroupSizes [i] = pat.Length;
+                                               }
+                                       } else {
+                                               numberGroupSizes = new int [1] { 0 };
+                                       }
+
+                                       if (posNeg [1].StartsWith ("(") && posNeg [1].EndsWith (")")) {
+                                               numberNegativePattern = 0;
+                                       } else if (posNeg [1].StartsWith ("- ")) {
+                                               numberNegativePattern = 2;
+                                       } else if (posNeg [1].StartsWith ("-")) {
+                                               numberNegativePattern = 1;
+                                       } else if (posNeg [1].EndsWith (" -")) {
+                                               numberNegativePattern = 4;
+                                       } else if (posNeg [1].EndsWith ("-")) {
+                                               numberNegativePattern = 3;
+                                       } else {
+                                               numberNegativePattern = 1;
+                                       }
+                               }
+                       }
+
+                       posNeg = currencyFormats.Split (new char [1] {';'}, 2);                 
+                       if (posNeg.Length == 2) {
+                               partOne = posNeg [0].Split (new char [1] {'.'}, 2);
+                               
+                               if (partOne.Length == 2) {
+                                       // assumed same for both positive and negative
+                                       // decimal digit side
+                                       currencyDecimalDigits = 0;
+                                       for (int i = 0; i < partOne [1].Length; i ++) {
+                                               if (partOne [1][i] == zeroPattern [0])
+                                                       currencyDecimalDigits ++;
+                                               else
+                                                       break;
+                                       }
+
+                                       // decimal grouping side
+                                       partTwo = partOne [0].Split (',');
+                                       if (partTwo.Length > 1) {                                               
+                                               currencyGroupSizes = new int [partTwo.Length - 1];
+                                               for (int i = 0; i < currencyGroupSizes.Length; i ++) {
+                                                       string pat = partTwo [i + 1];
+                                                       currencyGroupSizes [i] = pat.Length;
+                                               }
+                                       } else {
+                                               currencyGroupSizes = new int [1] { 0 };
+                                       }
+
+                                       if (posNeg [1].StartsWith ("(\u00a4 ") && posNeg [1].EndsWith (")")) {
+                                               currencyNegativePattern = 14;
+                                       } else if (posNeg [1].StartsWith ("(\u00a4") && posNeg [1].EndsWith (")")) {
+                                               currencyNegativePattern = 0;
+                                       } else if (posNeg [1].StartsWith ("\u00a4 ") && posNeg [1].EndsWith ("-")) {
+                                               currencyNegativePattern = 11;
+                                       } else if (posNeg [1].StartsWith ("\u00a4") && posNeg [1].EndsWith ("-")) {
+                                               currencyNegativePattern = 3;
+                                       } else if (posNeg [1].StartsWith ("(") && posNeg [1].EndsWith (" \u00a4")) {
+                                               currencyNegativePattern = 15;
+                                       } else if (posNeg [1].StartsWith ("(") && posNeg [1].EndsWith ("\u00a4")) {
+                                               currencyNegativePattern = 4;
+                                       } else if (posNeg [1].StartsWith ("-") && posNeg [1].EndsWith (" \u00a4")) {
+                                               currencyNegativePattern = 8;
+                                       } else if (posNeg [1].StartsWith ("-") && posNeg [1].EndsWith ("\u00a4")) {
+                                               currencyNegativePattern = 5;
+                                       } else if (posNeg [1].StartsWith ("-\u00a4 ")) {
+                                               currencyNegativePattern = 9;
+                                       } else if (posNeg [1].StartsWith ("-\u00a4")) {
+                                               currencyNegativePattern = 1;
+                                       } else if (posNeg [1].StartsWith ("\u00a4 -")) {
+                                               currencyNegativePattern = 12;
+                                       } else if (posNeg [1].StartsWith ("\u00a4-")) {
+                                               currencyNegativePattern = 2;
+                                       } else if (posNeg [1].EndsWith (" \u00a4-")) {
+                                               currencyNegativePattern = 10;
+                                       } else if (posNeg [1].EndsWith ("\u00a4-")) {
+                                               currencyNegativePattern = 7;
+                                       } else if (posNeg [1].EndsWith ("- \u00a4")) {
+                                               currencyNegativePattern = 13;
+                                       } else if (posNeg [1].EndsWith ("-\u00a4")) {
+                                               currencyNegativePattern = 6;
+                                       } else {
+                                               currencyNegativePattern = 0;
+                                       }
+                                       
+                                       if (posNeg [0].StartsWith ("\u00a4 ")) {
+                                               currencyPositivePattern = 2;
+                                       } else if (posNeg [0].StartsWith ("\u00a4")) {
+                                               currencyPositivePattern = 0;
+                                       } else if (posNeg [0].EndsWith (" \u00a4")) {
+                                               currencyPositivePattern = 3;
+                                       } else if (posNeg [0].EndsWith ("\u00a4")) {
+                                               currencyPositivePattern = 1; 
+                                       } else {
+                                               currencyPositivePattern = 0;
+                                       }
+                               }
+                       }
+
+                       // we don't have percentNegativePattern in CLDR so 
+                       // the percentNegativePattern are just guesses
+                       if (percentFormats.StartsWith ("%")) {
+                               percentPositivePattern = 2;
+                               percentNegativePattern = 2;
+                       } else if (percentFormats.EndsWith (" %")) {
+                               percentPositivePattern = 0;
+                               percentNegativePattern = 0;
+                       } else if (percentFormats.EndsWith ("%")) {
+                               percentPositivePattern = 1;
+                               percentNegativePattern = 1;
+                       } else {
+                               percentPositivePattern = 0;
+                               percentNegativePattern = 0;
+                       }
+
+                       partOne = percentFormats.Split (new char [1] {'.'}, 2);
+                       
+                       if (partOne.Length == 2) {
+                               // assumed same for both positive and negative
+                               // decimal digit side
+                               percentDecimalDigits = 0;
+                               for (int i = 0; i < partOne [1].Length; i ++) {
+                                       if (partOne [1][i] == digitPattern [0])
+                                               percentDecimalDigits ++;
+                                       else
+                                               break;
+                               }
+
+                               // percent grouping side
+                               partTwo = partOne [0].Split (',');
+                               if (partTwo.Length > 1) {
+                                       percentGroupSizes = new int [partTwo.Length - 1];
+                                       for (int i = 0; i < percentGroupSizes.Length; i ++) {
+                                               string pat = partTwo [i + 1];
+                                               percentGroupSizes [i] = pat.Length;
+                                       }
+                               } else {
+                                       percentGroupSizes = new int [1] { 0 };
+                               }
+                       }
+                       
+               }
+
                // =========== Currency Format Properties =========== //
 
                public int CurrencyDecimalDigits {
@@ -124,7 +348,7 @@ namespace System.Globalization {
                                        throw new ArgumentOutOfRangeException
                                        ("The value specified for the property is less than 0 or greater than 99");
                                
-                               if (readOnly)
+                               if (isReadOnly)
                                        throw new InvalidOperationException
                                        ("The current instance is read-only and a set operation was attempted");
 
@@ -142,7 +366,7 @@ namespace System.Globalization {
                                        throw new ArgumentNullException
                                        ("The value specified for the property is a null reference");
                                
-                               if (readOnly)
+                               if (isReadOnly)
                                        throw new InvalidOperationException
                                        ("The current instance is read-only and a set operation was attempted");
                                
@@ -161,7 +385,7 @@ namespace System.Globalization {
                                        throw new ArgumentNullException
                                        ("The value specified for the property is a null reference");
                        
-                               if (readOnly)
+                               if (isReadOnly)
                                        throw new InvalidOperationException
                                        ("The current instance is read-only and a set operation was attempted");        
                                
@@ -170,19 +394,34 @@ namespace System.Globalization {
                }
 
                public int[] CurrencyGroupSizes {
+                       get {
+                               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");
                                
-                               if (readOnly)
+                               if (isReadOnly)
                                        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;
 
@@ -210,7 +449,7 @@ namespace System.Globalization {
                                        throw new ArgumentOutOfRangeException
                                        ("The value specified for the property is less than 0 or greater than 15");
                                
-                               if (readOnly)
+                               if (isReadOnly)
                                        throw new InvalidOperationException
                                        ("The current instance is read-only and a set operation was attempted");
 
@@ -229,7 +468,7 @@ namespace System.Globalization {
                                        throw new ArgumentOutOfRangeException
                                        ("The value specified for the property is less than 0 or greater than 3");
                                
-                               if (readOnly)
+                               if (isReadOnly)
                                        throw new InvalidOperationException
                                        ("The current instance is read-only and a set operation was attempted");
 
@@ -247,7 +486,7 @@ namespace System.Globalization {
                                        throw new ArgumentNullException
                                        ("The value specified for the property is a null reference");
                        
-                               if (readOnly)
+                               if (isReadOnly)
                                        throw new InvalidOperationException
                                        ("The current instance is read-only and a set operation was attempted");        
                                
@@ -259,9 +498,8 @@ namespace System.Globalization {
 
                public static NumberFormatInfo CurrentInfo {
                        get {
-                               // This should be culture specific
-                               NumberFormatInfo nfi = new NumberFormatInfo ();
-                               nfi.readOnly = true;
+                               NumberFormatInfo nfi = (NumberFormatInfo) System.Threading.Thread.CurrentThread.CurrentCulture.NumberFormat;
+                               nfi.isReadOnly = true;
                                return nfi;
                        }                      
                }
@@ -271,14 +509,14 @@ namespace System.Globalization {
                                // This uses invariant info, which is same as in the constructor
                                NumberFormatInfo nfi = new NumberFormatInfo ();
                                nfi.NumberNegativePattern = 1;
-                               nfi.readOnly = true;
+                               nfi.isReadOnly = true;
                                return nfi;
                        }                      
                }
 
                public bool IsReadOnly {
                        get {
-                               return readOnly;
+                               return isReadOnly;
                        }
                }
 
@@ -286,7 +524,7 @@ namespace System.Globalization {
 
                public string NaNSymbol {
                        get {
-                               return naNSymbol;
+                               return nanSymbol;
                        }
                        
                        set {
@@ -294,13 +532,38 @@ namespace System.Globalization {
                                        throw new ArgumentNullException
                                        ("The value specified for the property is a null reference");
                        
-                               if (readOnly)
+                               if (isReadOnly)
                                        throw new InvalidOperationException
                                        ("The current instance is read-only and a set operation was attempted");        
                                
-                               naNSymbol = value;
+                               nanSymbol = value;
+                       }
+               }
+               
+#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 {
@@ -312,7 +575,7 @@ namespace System.Globalization {
                                        throw new ArgumentNullException
                                        ("The value specified for the property is a null reference");
                        
-                               if (readOnly)
+                               if (isReadOnly)
                                        throw new InvalidOperationException
                                        ("The current instance is read-only and a set operation was attempted");        
                                
@@ -330,7 +593,7 @@ namespace System.Globalization {
                                        throw new ArgumentNullException
                                        ("The value specified for the property is a null reference");
                        
-                               if (readOnly)
+                               if (isReadOnly)
                                        throw new InvalidOperationException
                                        ("The current instance is read-only and a set operation was attempted");        
                                
@@ -350,7 +613,7 @@ namespace System.Globalization {
                                        throw new ArgumentOutOfRangeException
                                        ("The value specified for the property is less than 0 or greater than 99");
                                
-                               if (readOnly)
+                               if (isReadOnly)
                                        throw new InvalidOperationException
                                        ("The current instance is read-only and a set operation was attempted");
 
@@ -368,7 +631,7 @@ namespace System.Globalization {
                                        throw new ArgumentNullException
                                        ("The value specified for the property is a null reference");
                                
-                               if (readOnly)
+                               if (isReadOnly)
                                        throw new InvalidOperationException
                                        ("The current instance is read-only and a set operation was attempted");
                                
@@ -387,7 +650,7 @@ namespace System.Globalization {
                                        throw new ArgumentNullException
                                        ("The value specified for the property is a null reference");
                        
-                               if (readOnly)
+                               if (isReadOnly)
                                        throw new InvalidOperationException
                                        ("The current instance is read-only and a set operation was attempted");        
                                
@@ -396,19 +659,33 @@ namespace System.Globalization {
                }
 
                public int[] NumberGroupSizes {
+                       get {
+                               return (int []) RawNumberGroupSizes.Clone ();
+                       }
+                       
+                       set {
+                               RawNumberGroupSizes = value;
+                       }
+               }
+
+               internal int[] RawNumberGroupSizes {
                        get {
                                return numberGroupSizes;
                        }
                        
                        set {
-                               if (value == null || value.Length == 0
+                               if (value == null) 
                                        throw new ArgumentNullException
                                        ("The value specified for the property is a null reference");
                                
-                               if (readOnly)
+                               if (isReadOnly)
                                        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;
 
@@ -436,7 +713,7 @@ namespace System.Globalization {
                                        throw new ArgumentOutOfRangeException
                                        ("The value specified for the property is less than 0 or greater than 15");
                                
-                               if (readOnly)
+                               if (isReadOnly)
                                        throw new InvalidOperationException
                                        ("The current instance is read-only and a set operation was attempted");
 
@@ -456,7 +733,7 @@ namespace System.Globalization {
                                        throw new ArgumentOutOfRangeException
                                        ("The value specified for the property is less than 0 or greater than 99");
                                
-                               if (readOnly)
+                               if (isReadOnly)
                                        throw new InvalidOperationException
                                        ("The current instance is read-only and a set operation was attempted");
 
@@ -474,7 +751,7 @@ namespace System.Globalization {
                                        throw new ArgumentNullException
                                        ("The value specified for the property is a null reference");
                                
-                               if (readOnly)
+                               if (isReadOnly)
                                        throw new InvalidOperationException
                                        ("The current instance is read-only and a set operation was attempted");
                                
@@ -493,7 +770,7 @@ namespace System.Globalization {
                                        throw new ArgumentNullException
                                        ("The value specified for the property is a null reference");
                        
-                               if (readOnly)
+                               if (isReadOnly)
                                        throw new InvalidOperationException
                                        ("The current instance is read-only and a set operation was attempted");        
                                
@@ -502,19 +779,37 @@ namespace System.Globalization {
                }
 
                public int[] PercentGroupSizes {
+                       get {
+                               return (int []) RawPercentGroupSizes.Clone ();
+                       }
+                       
+                       set {
+                               RawPercentGroupSizes = value;
+                       }
+               }
+
+               internal int[] RawPercentGroupSizes {
                        get {
                                return percentGroupSizes;
                        }
                        
                        set {
-                               if (value == null || value.Length == 0
+                               if (value == null) 
                                        throw new ArgumentNullException
                                        ("The value specified for the property is a null reference");
                                
-                               if (readOnly)
+                               if (isReadOnly)
                                        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 (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;
 
@@ -542,7 +837,7 @@ namespace System.Globalization {
                                        throw new ArgumentOutOfRangeException
                                        ("The value specified for the property is less than 0 or greater than 15");
                                
-                               if (readOnly)
+                               if (isReadOnly)
                                        throw new InvalidOperationException
                                        ("The current instance is read-only and a set operation was attempted");
 
@@ -561,7 +856,7 @@ namespace System.Globalization {
                                        throw new ArgumentOutOfRangeException
                                        ("The value specified for the property is less than 0 or greater than 3");
                                
-                               if (readOnly)
+                               if (isReadOnly)
                                        throw new InvalidOperationException
                                        ("The current instance is read-only and a set operation was attempted");
 
@@ -579,7 +874,7 @@ namespace System.Globalization {
                                        throw new ArgumentNullException
                                        ("The value specified for the property is a null reference");
                        
-                               if (readOnly)
+                               if (isReadOnly)
                                        throw new InvalidOperationException
                                        ("The current instance is read-only and a set operation was attempted");        
                                
@@ -597,7 +892,7 @@ namespace System.Globalization {
                                        throw new ArgumentNullException
                                        ("The value specified for the property is a null reference");
                                
-                               if (readOnly)
+                               if (isReadOnly)
                                        throw new InvalidOperationException
                                        ("The current instance is read-only and a set operation was attempted");
                                
@@ -615,7 +910,7 @@ namespace System.Globalization {
                                        throw new ArgumentNullException
                                        ("The value specified for the property is a null reference");
                        
-                               if (readOnly)
+                               if (isReadOnly)
                                        throw new InvalidOperationException
                                        ("The current instance is read-only and a set operation was attempted");        
                                
@@ -633,7 +928,7 @@ namespace System.Globalization {
                                        throw new ArgumentNullException
                                        ("The value specified for the property is a null reference");
                        
-                               if (readOnly)
+                               if (isReadOnly)
                                        throw new InvalidOperationException
                                        ("The current instance is read-only and a set operation was attempted");        
                                
@@ -643,21 +938,21 @@ namespace System.Globalization {
 
                public object GetFormat (Type formatType) 
                {
-                       return (formatType == GetType()) ? this : null;
+                       return (formatType == typeof (NumberFormatInfo)) ? this : null;
                }
                
                public object Clone () 
                {
                        NumberFormatInfo clone = (NumberFormatInfo) MemberwiseClone();
                        // clone is not read only
-                       clone.readOnly = false;
+                       clone.isReadOnly = false;
                        return clone;
                }
 
                public static NumberFormatInfo ReadOnly (NumberFormatInfo nfi)
                {
                        NumberFormatInfo copy = (NumberFormatInfo)nfi.Clone();
-                       copy.readOnly = true;
+                       copy.isReadOnly = true;
                        return copy;
                }