Merge pull request #697 from linquize/atom-bug
[mono.git] / mcs / class / corlib / System.Collections / CaseInsensitiveHashCodeProvider.cs
index c851a1004b27c15eb1c72245a42ca46455021245..0a273dacc8f9e9dc67d30d7f689943fa37b5e271 100644 (file)
@@ -34,35 +34,36 @@ using System.Runtime.InteropServices;
 namespace System.Collections
 {
        [Serializable]
-#if NET_2_0
        [ComVisible(true)]
        [Obsolete ("Please use StringComparer instead.")]
+#if INSIDE_CORLIB
+       public
+#else
+       internal
 #endif
-       public class CaseInsensitiveHashCodeProvider : IHashCodeProvider
+       class CaseInsensitiveHashCodeProvider : IHashCodeProvider
        {
-               static readonly CaseInsensitiveHashCodeProvider singleton = new CaseInsensitiveHashCodeProvider ();
-               static readonly CaseInsensitiveHashCodeProvider singletonInvariant = new CaseInsensitiveHashCodeProvider (true);
+               static readonly CaseInsensitiveHashCodeProvider singletonInvariant = new CaseInsensitiveHashCodeProvider (
+                       CultureInfo.InvariantCulture);
+               static CaseInsensitiveHashCodeProvider singleton;
+               static readonly object sync = new object ();
 
                TextInfo m_text; // must match MS name for serialization
 
                // Public instance constructor
                public CaseInsensitiveHashCodeProvider ()
                {
-                       m_text = CultureInfo.CurrentCulture.TextInfo;
-               }
-
-               private CaseInsensitiveHashCodeProvider (bool invariant)
-               {
-                       // leave m_text == null
+                       CultureInfo culture = CultureInfo.CurrentCulture;
+                       if (!AreEqual (culture, CultureInfo.InvariantCulture))
+                               m_text = CultureInfo.CurrentCulture.TextInfo;
                }
 
                public CaseInsensitiveHashCodeProvider (CultureInfo culture)
                {
                        if (culture == null)
                                throw new ArgumentNullException ("culture");
-                       if (culture.LCID != CultureInfo.InvariantCulture.LCID)
+                       if (!AreEqual (culture, CultureInfo.InvariantCulture))
                                m_text = culture.TextInfo;
-                       // else leave m_text == null
                }
 
                //
@@ -71,15 +72,42 @@ namespace System.Collections
 
                public static CaseInsensitiveHashCodeProvider Default {
                        get {
-                               return singleton;
+                               // MS actually constructs a new instance on each call, for
+                               // performance reasons we're only constructing a new instance
+                               // if the CurrentCulture changes
+                               lock (sync) {
+                                       if (singleton == null) {
+                                               singleton = new CaseInsensitiveHashCodeProvider ();
+                                       } else if (singleton.m_text == null) {
+                                               if (!AreEqual (CultureInfo.CurrentCulture, CultureInfo.InvariantCulture))
+                                                       singleton = new CaseInsensitiveHashCodeProvider ();
+                                       } else if (!AreEqual (singleton.m_text, CultureInfo.CurrentCulture)) {
+                                               singleton = new CaseInsensitiveHashCodeProvider ();
+                                       }
+                                       return singleton;
+                               }
                        }
                }
 
-#if NET_1_1
-               public
+               static bool AreEqual (CultureInfo a, CultureInfo b)
+               {
+#if !NET_2_1
+                       return a.LCID == b.LCID;
 #else
-               internal
+                       return a.Name == b.Name;
 #endif
+               }
+
+               static bool AreEqual (TextInfo info, CultureInfo culture)
+               {
+#if !NET_2_1
+                       return info.LCID == culture.LCID;
+#else
+                       return info.CultureName == culture.Name;
+#endif
+               }
+
+               public
                static CaseInsensitiveHashCodeProvider DefaultInvariant {
                        get {
                                return singletonInvariant;
@@ -103,7 +131,7 @@ namespace System.Collections
                        int h = 0;
                        char c;
 
-                       if ((m_text != null) && (m_text.LCID != CultureInfo.InvariantCulture.LCID)) {
+                       if ((m_text != null) && !AreEqual (m_text, CultureInfo.InvariantCulture)) {
                                str = m_text.ToLower (str);
                                for (int i = 0; i < str.Length; i++) {
                                        c = str [i];
@@ -111,7 +139,7 @@ namespace System.Collections
                                }
                        } else {
                                for (int i = 0; i < str.Length; i++) {
-                                       c = Char.ToLowerInvariant (str [i]);
+                                       c = Char.ToLower (str [i], CultureInfo.InvariantCulture);
                                        h = h * 31 + c;
                                }
                        }