Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/mono/mono.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNeale <neale@sinenomine.net>2013-04-17 06:27:47 +0400
committerNeale <neale@sinenomine.net>2013-04-17 06:27:47 +0400
commitf19a364025edc23559597e24ea332890f3b1e0ff (patch)
tree8fa5d5d37820b101b5abfdf335bd616193ce880a
parent1f739060e594cc427676bd36ebf8bb8701736023 (diff)
When .NET serializes it will use the TypeForwardedFrom information whenmono-3.0.10-windows
writing Assembly information but Mono does not. This means that serialized objects created on one platform are not able to be deserialized on the other, thus preventing interoperability between .NET and mono applications. Fixes the ObservableCollection part of bugzilla 11294.
-rw-r--r--mcs/class/System/System.Collections.ObjectModel/ObservableCollection.cs25
-rw-r--r--mcs/class/WindowsBase/System.Collections.ObjectModel/ObservableCollection.cs8
-rw-r--r--mcs/class/corlib/System.Runtime.Serialization.Formatters.Binary/CodeGenerator.cs17
-rw-r--r--mcs/class/corlib/System.Runtime.Serialization.Formatters.Binary/ObjectWriter.cs46
4 files changed, 78 insertions, 18 deletions
diff --git a/mcs/class/System/System.Collections.ObjectModel/ObservableCollection.cs b/mcs/class/System/System.Collections.ObjectModel/ObservableCollection.cs
index 6c26e8795f6..32926907e21 100644
--- a/mcs/class/System/System.Collections.ObjectModel/ObservableCollection.cs
+++ b/mcs/class/System/System.Collections.ObjectModel/ObservableCollection.cs
@@ -40,30 +40,33 @@ namespace System.Collections.ObjectModel
#endif
public class ObservableCollection<T> : Collection<T>, INotifyCollectionChanged, INotifyPropertyChanged {
[Serializable]
- sealed class Reentrant : IDisposable {
- private int count = 0;
+#if !MOBILE
+ [TypeForwardedFrom (Consts.WindowsBase_3_0)]
+#endif
+ sealed class SimpleMonitor : IDisposable {
+ private int _busyCount = 0;
- public Reentrant()
+ public SimpleMonitor()
{
}
public void Enter()
{
- count++;
+ _busyCount++;
}
public void Dispose()
{
- count--;
+ _busyCount--;
}
public bool Busy
{
- get { return count > 0; }
+ get { return _busyCount > 0; }
}
}
- private Reentrant reentrant = new Reentrant ();
+ private SimpleMonitor _monitor = new SimpleMonitor ();
public ObservableCollection ()
{
@@ -83,7 +86,9 @@ namespace System.Collections.ObjectModel
{
}
+ [field:NonSerializedAttribute()]
public virtual event NotifyCollectionChangedEventHandler CollectionChanged;
+ [field:NonSerializedAttribute()]
protected virtual event PropertyChangedEventHandler PropertyChanged;
event PropertyChangedEventHandler INotifyPropertyChanged.PropertyChanged {
@@ -93,8 +98,8 @@ namespace System.Collections.ObjectModel
protected IDisposable BlockReentrancy ()
{
- reentrant.Enter ();
- return reentrant;
+ _monitor.Enter ();
+ return _monitor;
}
protected void CheckReentrancy ()
@@ -102,7 +107,7 @@ namespace System.Collections.ObjectModel
NotifyCollectionChangedEventHandler eh = CollectionChanged;
// Only have a problem if we have more than one event listener.
- if (reentrant.Busy && eh != null && eh.GetInvocationList ().Length > 1)
+ if (_monitor.Busy && eh != null && eh.GetInvocationList ().Length > 1)
throw new InvalidOperationException ("Cannot modify the collection while reentrancy is blocked.");
}
diff --git a/mcs/class/WindowsBase/System.Collections.ObjectModel/ObservableCollection.cs b/mcs/class/WindowsBase/System.Collections.ObjectModel/ObservableCollection.cs
index 1ea166cd9ac..bcc4440e109 100644
--- a/mcs/class/WindowsBase/System.Collections.ObjectModel/ObservableCollection.cs
+++ b/mcs/class/WindowsBase/System.Collections.ObjectModel/ObservableCollection.cs
@@ -44,7 +44,7 @@ namespace System.Collections.ObjectModel
public class ObservableCollection<T> : Collection<T>, INotifyCollectionChanged, INotifyPropertyChanged {
private class Reentrant : IDisposable {
- private int count = 0;
+ private int _busyCount = 0;
public Reentrant()
{
@@ -52,17 +52,17 @@ namespace System.Collections.ObjectModel
public void Enter()
{
- count++;
+ _busyCount++;
}
public void Dispose()
{
- count--;
+ _busyCount--;
}
public bool Busy
{
- get { return count > 0; }
+ get { return _busyCount > 0; }
}
}
diff --git a/mcs/class/corlib/System.Runtime.Serialization.Formatters.Binary/CodeGenerator.cs b/mcs/class/corlib/System.Runtime.Serialization.Formatters.Binary/CodeGenerator.cs
index fd38471644b..671c196163e 100644
--- a/mcs/class/corlib/System.Runtime.Serialization.Formatters.Binary/CodeGenerator.cs
+++ b/mcs/class/corlib/System.Runtime.Serialization.Formatters.Binary/CodeGenerator.cs
@@ -115,8 +115,13 @@ namespace System.Runtime.Serialization.Formatters.Binary
// EMIT ow.WriteAssembly (writer, memberType.Assembly);
gen.Emit (OpCodes.Ldarg_1);
gen.Emit (OpCodes.Ldarg_2);
+#if NET_4_0
+ EmitLoadType (gen, memberType);
+ gen.EmitCall (OpCodes.Callvirt, typeof(ObjectWriter).GetMethod("WriteTypeAssembly"), null);
+#else
EmitLoadTypeAssembly (gen, memberType, field.Name);
gen.EmitCall (OpCodes.Callvirt, typeof(ObjectWriter).GetMethod("WriteAssembly"), null);
+#endif
gen.Emit (OpCodes.Pop);
}
}
@@ -292,8 +297,14 @@ namespace System.Runtime.Serialization.Formatters.Binary
// EMIT writer.Write ((int)ow.GetAssemblyId (type.Assembly));
gen.Emit (OpCodes.Ldarg_2);
gen.Emit (OpCodes.Ldarg_1);
+#if NET_4_0
+ EmitLoadType (gen, type);
+ gen.EmitCall (OpCodes.Callvirt, typeof(GetForwardedAttribute).GetMethod("GetAssemblyName"), null);
+ gen.EmitCall (OpCodes.Callvirt, typeof(ObjectWriter).GetMethod("GetAssemblyNameId"), null);
+#else
EmitLoadTypeAssembly (gen, type, member);
gen.EmitCall (OpCodes.Callvirt, typeof(ObjectWriter).GetMethod("GetAssemblyId"), null);
+#endif
gen.Emit (OpCodes.Conv_I4);
EmitWrite (gen, typeof(int));
break;
@@ -318,6 +329,12 @@ namespace System.Runtime.Serialization.Formatters.Binary
gen.EmitCall (OpCodes.Callvirt, typeof(Type).GetProperty("Assembly").GetGetMethod(), null);
}
+ static void EmitLoadType (ILGenerator gen, Type type)
+ {
+ gen.Emit (OpCodes.Ldtoken, type);
+ gen.EmitCall (OpCodes.Call, typeof(Type).GetMethod("GetTypeFromHandle"), null);
+ }
+
static void EmitWrite (ILGenerator gen, Type type)
{
gen.EmitCall (OpCodes.Callvirt, typeof(BinaryWriter).GetMethod("Write", new Type[] { type }), null);
diff --git a/mcs/class/corlib/System.Runtime.Serialization.Formatters.Binary/ObjectWriter.cs b/mcs/class/corlib/System.Runtime.Serialization.Formatters.Binary/ObjectWriter.cs
index 9d3c42bbd19..c5bf658a1c8 100644
--- a/mcs/class/corlib/System.Runtime.Serialization.Formatters.Binary/ObjectWriter.cs
+++ b/mcs/class/corlib/System.Runtime.Serialization.Formatters.Binary/ObjectWriter.cs
@@ -35,9 +35,25 @@ using System.Runtime.Serialization;
using System.Runtime.Remoting.Messaging;
using System.Reflection;
using System.Globalization;
+using System.Runtime.CompilerServices;
namespace System.Runtime.Serialization.Formatters.Binary
{
+#if NET_4_0
+ public class GetForwardedAttribute
+ {
+ public static string GetAssemblyName (Type self)
+ {
+ var attrs = self.GetCustomAttributes(
+ typeof (TypeForwardedFromAttribute), false);
+ if (attrs.Length == 0)
+ return self.Assembly.FullName;
+ else
+ return ((TypeForwardedFromAttribute)attrs [0]).AssemblyFullName;
+ }
+ }
+#endif
+
abstract class TypeMetadata
{
public string TypeAssemblyName;
@@ -73,7 +89,11 @@ namespace System.Runtime.Serialization.Formatters.Binary
{
InstanceType = instanceType;
InstanceTypeName = instanceType.FullName;
+#if NET_4_0
+ TypeAssemblyName = GetForwardedAttribute.GetAssemblyName(instanceType);
+#else
TypeAssemblyName = instanceType.Assembly.FullName;
+#endif
}
public override bool RequiresTypes {
@@ -102,7 +122,11 @@ namespace System.Runtime.Serialization.Formatters.Binary
}
TypeAssemblyName = info.AssemblyName;
+#if NET_4_0
+ InstanceTypeName = GetForwardedAttribute.GetAssemblyName(itype);
+#else
InstanceTypeName = info.FullTypeName;
+#endif
}
public override bool IsCompatible (TypeMetadata other)
@@ -129,7 +153,7 @@ namespace System.Runtime.Serialization.Formatters.Binary
while (type.IsArray)
type = type.GetElementType();
- ow.WriteAssembly (writer, type.Assembly);
+ ow.WriteTypeAssembly (writer, type);
}
}
@@ -142,7 +166,7 @@ namespace System.Runtime.Serialization.Formatters.Binary
writer.Write (name);
// Types of fields
- foreach (Type type in types)
+ foreach (Type type in types)
ObjectWriter.WriteTypeCode (writer, type);
// Type specs of fields
@@ -181,7 +205,7 @@ namespace System.Runtime.Serialization.Formatters.Binary
while (type.IsArray)
type = type.GetElementType();
- ow.WriteAssembly (writer, type.Assembly);
+ ow.WriteTypeAssembly (writer, type);
}
}
@@ -511,7 +535,7 @@ namespace System.Runtime.Serialization.Formatters.Binary
var tag = GetTypeTag (elementType);
if ((tag != TypeTag.ArrayOfObject) && (tag != TypeTag.ArrayOfString) && (tag != TypeTag.ArrayOfPrimitiveType))
- WriteAssembly (writer, elementType.Assembly);
+ WriteTypeAssembly (writer, elementType);
// Writes the array
@@ -809,6 +833,15 @@ namespace System.Runtime.Serialization.Formatters.Binary
writer.Write (str);
}
+ public int WriteTypeAssembly (BinaryWriter writer, Type aType)
+ {
+#if NET_4_0
+ return WriteAssemblyName (writer, GetForwardedAttribute.GetAssemblyName(aType));
+#else
+ return WriteAssemblyName (writer, aType.Assembly.FullName);
+#endif
+ }
+
public int WriteAssembly (BinaryWriter writer, Assembly assembly)
{
return WriteAssemblyName (writer, assembly.FullName);
@@ -994,7 +1027,12 @@ namespace System.Runtime.Serialization.Formatters.Binary
case TypeTag.GenericType:
writer.Write (type.FullName);
+#if NET_4_0
+ string asmName = GetForwardedAttribute.GetAssemblyName(type);
+ writer.Write ((int) GetAssemblyNameId (asmName));
+#else
writer.Write ((int)GetAssemblyId (type.Assembly));
+#endif
break;
case TypeTag.ArrayOfPrimitiveType: