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);
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);
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 ()]);
+ }
}
}