In System.Collections.Generic:
authorRobert Jordan <robertj@gmx.net>
Sun, 24 Jan 2010 01:04:18 +0000 (01:04 -0000)
committerRobert Jordan <robertj@gmx.net>
Sun, 24 Jan 2010 01:04:18 +0000 (01:04 -0000)
2010-01-24  Robert Jordan  <robertj@gmx.net>

* Dictionary.cs: Fix deserialization compatibility with MS.NET.
Fixes bug #474009.

In Test/System.Collections.Generic:
2010-01-24  Robert Jordan  <robertj@gmx.net>

* DictionaryTest.cs: Add test case for bug #474009.

svn path=/trunk/mcs/; revision=150089

mcs/class/corlib/System.Collections.Generic/ChangeLog
mcs/class/corlib/System.Collections.Generic/Dictionary.cs
mcs/class/corlib/Test/System.Collections.Generic/ChangeLog
mcs/class/corlib/Test/System.Collections.Generic/DictionaryTest.cs

index 6bce4cfb66d8620f56fe2ac5b716f00760073fcc..2ff36e7a854430b5bf184e784d1ca5050699d877 100644 (file)
@@ -1,3 +1,8 @@
+2010-01-24  Robert Jordan  <robertj@gmx.net>
+
+       * Dictionary.cs: Fix deserialization compatibility with MS.NET.
+       Fixes bug #474009.
+
 2010-01-20  Miguel de Icaza  <miguel@novell.com>
 
        * Dictionary.cs: Always create the keys, fixes compatibility
index 91d3cc312bc45f7ecc1847a89612051975773aae..65d88dbde3731eb7fb3943b8ab443a97d3562399 100644 (file)
@@ -501,8 +501,11 @@ namespace System.Collections.Generic {
 
                        info.AddValue ("Version", generation);
                        info.AddValue ("Comparer", hcp);
-                       KeyValuePair<TKey, TValue> [] data = null;
-                       data = new KeyValuePair<TKey,TValue> [count];
+                       // MS.NET expects either *no* KeyValuePairs field (when count = 0)
+                       // or a non-null KeyValuePairs field. We don't omit the field to
+                       // remain compatible with older monos, but we also doesn't serialize
+                       // it as null to make MS.NET happy.
+                       KeyValuePair<TKey, TValue> [] data = new KeyValuePair<TKey,TValue> [count];
                        if (count > 0)
                                CopyTo (data, 0);
                        info.AddValue ("HashSize", table.Length);
@@ -514,14 +517,34 @@ namespace System.Collections.Generic {
                        if (serialization_info == null)
                                return;
 
-                       generation = serialization_info.GetInt32 ("Version");
-                       hcp = (IEqualityComparer<TKey>) serialization_info.GetValue ("Comparer", typeof (IEqualityComparer<TKey>));
+                       int hashSize = 0;
+                       KeyValuePair<TKey, TValue> [] data = null;
+
+                       // We must use the enumerator because MS.NET doesn't
+                       // serialize "KeyValuePairs" for count = 0.
+                       SerializationInfoEnumerator e = serialization_info.GetEnumerator ();
+                       while (e.MoveNext ()) {
+                               switch (e.Name) {
+                               case "Version":
+                                       generation = (int) e.Value;
+                                       break;
+
+                               case "Comparer":
+                                       hcp = (IEqualityComparer<TKey>) e.Value;
+                                       break;
 
-                       int hashSize = serialization_info.GetInt32 ("HashSize");
-                       KeyValuePair<TKey, TValue> [] data =
-                               (KeyValuePair<TKey, TValue> [])
-                               serialization_info.GetValue ("KeyValuePairs", typeof (KeyValuePair<TKey, TValue> []));
+                               case "HashSize":
+                                       hashSize = (int) e.Value;
+                                       break;
+
+                               case "KeyValuePairs":
+                                       data = (KeyValuePair<TKey, TValue> []) e.Value;
+                                       break;
+                               }
+                       }
 
+                       if (hcp == null)
+                               hcp = EqualityComparer<TKey>.Default;
                        if (hashSize < INITIAL_SIZE)
                                hashSize = INITIAL_SIZE;
                        InitArrays (hashSize);
index 70172f0ce0452440984d3b3aa39fc20999f6ed26..be9b884695b3b652d2e3bc9a2768b8165c2aea3d 100644 (file)
@@ -1,3 +1,7 @@
+2010-01-24  Robert Jordan  <robertj@gmx.net>
+
+       * DictionaryTest.cs: Add test case for bug #474009.
+
 2009-09-22  Raja R Harinath  <harinath@hurrynot.org>
 
        * DictionaryTest.cs (ICollectionCopyTo): Test various odd
index 0afa477bfc4ece81377dcd97a165fafdec78eda8..b429c6437efaf810ee737cbbeaaa1606cbce110b 100644 (file)
@@ -1166,6 +1166,70 @@ namespace MonoTests.System.Collections.Generic {
                        ICollection c = d.Values;
                        c.CopyTo (new MyClass [1], 0);
                }
+
+               [Test] // bug 474009
+               public void DeserializeEmptyDictionary ()
+               {
+                       // contains a Dictionary<string, int> with Count = 0
+                       // serialized with MS.NET 3.5
+                       string data =
+@"AAEAAAD/////AQAAAAAAAAAEAQAAAOEBU3lzdGVtLkNvbGxlY3Rpb25zLkdlbmVyaWMuRGljdGlv
+bmFyeWAyW1tTeXN0ZW0uU3RyaW5nLCBtc2NvcmxpYiwgVmVyc2lvbj0yLjAuMC4wLCBDdWx0dXJl
+PW5ldXRyYWwsIFB1YmxpY0tleVRva2VuPWI3N2E1YzU2MTkzNGUwODldLFtTeXN0ZW0uSW50MzIs
+IG1zY29ybGliLCBWZXJzaW9uPTIuMC4wLjAsIEN1bHR1cmU9bmV1dHJhbCwgUHVibGljS2V5VG9r
+ZW49Yjc3YTVjNTYxOTM0ZTA4OV1dAwAAAAdWZXJzaW9uCENvbXBhcmVyCEhhc2hTaXplAAMACJIB
+U3lzdGVtLkNvbGxlY3Rpb25zLkdlbmVyaWMuR2VuZXJpY0VxdWFsaXR5Q29tcGFyZXJgMVtbU3lz
+dGVtLlN0cmluZywgbXNjb3JsaWIsIFZlcnNpb249Mi4wLjAuMCwgQ3VsdHVyZT1uZXV0cmFsLCBQ
+dWJsaWNLZXlUb2tlbj1iNzdhNWM1NjE5MzRlMDg5XV0IAAAAAAkCAAAAAAAAAAQCAAAAkgFTeXN0
+ZW0uQ29sbGVjdGlvbnMuR2VuZXJpYy5HZW5lcmljRXF1YWxpdHlDb21wYXJlcmAxW1tTeXN0ZW0u
+U3RyaW5nLCBtc2NvcmxpYiwgVmVyc2lvbj0yLjAuMC4wLCBDdWx0dXJlPW5ldXRyYWwsIFB1Ymxp
+Y0tleVRva2VuPWI3N2E1YzU2MTkzNGUwODldXQAAAAAL";
+
+                       var stream = new MemoryStream (Convert.FromBase64String (data));
+                       var fmt = new BinaryFormatter ();
+                       var dict = (Dictionary <string, int>) fmt.Deserialize (stream);
+                       Assert.AreEqual (0, dict.Count);
+               }
+
+               [Test]
+               public void DeserializeNonEmptyDictionary ()
+               {
+                       // contains a Dictionary<string, int> with Count = 2
+                       // and dict [i.ToString()] == i for each i.
+                       // serialized with MS.NET 3.5
+                       string data =
+@"AAEAAAD/////AQAAAAAAAAAEAQAAAOEBU3lzdGVtLkNvbGxlY3Rpb25zLkdlbmVyaWMuRGljdGlv
+bmFyeWAyW1tTeXN0ZW0uU3RyaW5nLCBtc2NvcmxpYiwgVmVyc2lvbj0yLjAuMC4wLCBDdWx0dXJl
+PW5ldXRyYWwsIFB1YmxpY0tleVRva2VuPWI3N2E1YzU2MTkzNGUwODldLFtTeXN0ZW0uSW50MzIs
+IG1zY29ybGliLCBWZXJzaW9uPTIuMC4wLjAsIEN1bHR1cmU9bmV1dHJhbCwgUHVibGljS2V5VG9r
+ZW49Yjc3YTVjNTYxOTM0ZTA4OV1dBAAAAAdWZXJzaW9uCENvbXBhcmVyCEhhc2hTaXplDUtleVZh
+bHVlUGFpcnMAAwADCJIBU3lzdGVtLkNvbGxlY3Rpb25zLkdlbmVyaWMuR2VuZXJpY0VxdWFsaXR5
+Q29tcGFyZXJgMVtbU3lzdGVtLlN0cmluZywgbXNjb3JsaWIsIFZlcnNpb249Mi4wLjAuMCwgQ3Vs
+dHVyZT1uZXV0cmFsLCBQdWJsaWNLZXlUb2tlbj1iNzdhNWM1NjE5MzRlMDg5XV0I5QFTeXN0ZW0u
+Q29sbGVjdGlvbnMuR2VuZXJpYy5LZXlWYWx1ZVBhaXJgMltbU3lzdGVtLlN0cmluZywgbXNjb3Js
+aWIsIFZlcnNpb249Mi4wLjAuMCwgQ3VsdHVyZT1uZXV0cmFsLCBQdWJsaWNLZXlUb2tlbj1iNzdh
+NWM1NjE5MzRlMDg5XSxbU3lzdGVtLkludDMyLCBtc2NvcmxpYiwgVmVyc2lvbj0yLjAuMC4wLCBD
+dWx0dXJlPW5ldXRyYWwsIFB1YmxpY0tleVRva2VuPWI3N2E1YzU2MTkzNGUwODldXVtdAgAAAAkC
+AAAAAwAAAAkDAAAABAIAAACSAVN5c3RlbS5Db2xsZWN0aW9ucy5HZW5lcmljLkdlbmVyaWNFcXVh
+bGl0eUNvbXBhcmVyYDFbW1N5c3RlbS5TdHJpbmcsIG1zY29ybGliLCBWZXJzaW9uPTIuMC4wLjAs
+IEN1bHR1cmU9bmV1dHJhbCwgUHVibGljS2V5VG9rZW49Yjc3YTVjNTYxOTM0ZTA4OV1dAAAAAAcD
+AAAAAAEAAAACAAAAA+MBU3lzdGVtLkNvbGxlY3Rpb25zLkdlbmVyaWMuS2V5VmFsdWVQYWlyYDJb
+W1N5c3RlbS5TdHJpbmcsIG1zY29ybGliLCBWZXJzaW9uPTIuMC4wLjAsIEN1bHR1cmU9bmV1dHJh
+bCwgUHVibGljS2V5VG9rZW49Yjc3YTVjNTYxOTM0ZTA4OV0sW1N5c3RlbS5JbnQzMiwgbXNjb3Js
+aWIsIFZlcnNpb249Mi4wLjAuMCwgQ3VsdHVyZT1uZXV0cmFsLCBQdWJsaWNLZXlUb2tlbj1iNzdh
+NWM1NjE5MzRlMDg5XV0E/P///+MBU3lzdGVtLkNvbGxlY3Rpb25zLkdlbmVyaWMuS2V5VmFsdWVQ
+YWlyYDJbW1N5c3RlbS5TdHJpbmcsIG1zY29ybGliLCBWZXJzaW9uPTIuMC4wLjAsIEN1bHR1cmU9
+bmV1dHJhbCwgUHVibGljS2V5VG9rZW49Yjc3YTVjNTYxOTM0ZTA4OV0sW1N5c3RlbS5JbnQzMiwg
+bXNjb3JsaWIsIFZlcnNpb249Mi4wLjAuMCwgQ3VsdHVyZT1uZXV0cmFsLCBQdWJsaWNLZXlUb2tl
+bj1iNzdhNWM1NjE5MzRlMDg5XV0CAAAAA2tleQV2YWx1ZQEACAYFAAAAATAAAAAAAfr////8////
+BgcAAAABMQEAAAAL";
+                       var stream = new MemoryStream (Convert.FromBase64String (data));
+                       var fmt = new BinaryFormatter ();
+                       var dict = (Dictionary <string, int>) fmt.Deserialize (stream);
+                       Assert.AreEqual (2, dict.Count);
+                       for (int i = 0; i < dict.Count; i++)
+                               Assert.AreEqual (i, dict[i.ToString ()]);
+               }
        }
 }