[Mono-patches] mcs/class/corlib/System DelegateSerializationHolder.cs,NONE,1.1 UnitySerializationHolder.cs,NONE,1.1 ChangeLog,1.449,1.450 DBNull.cs,1.1,1.2 Delegate.cs,1.22,1.23 MonoType.cs,1.37,1.38 Type.cs,1.66,1.67

Lluis Sanchez <lsg@ctv.es> lluis@mono-cvs.ximian.com
Fri, 17 Jan 2003 09:16:44 -0500


Update of /cvs/public/mcs/class/corlib/System
In directory mono-cvs.ximian.com:/tmp/cvs-serv3759

Modified Files:
	ChangeLog DBNull.cs Delegate.cs MonoType.cs Type.cs 
Added Files:
	DelegateSerializationHolder.cs UnitySerializationHolder.cs 
Log Message:
* Type.cs: corrected property IsSerializable. It should always return true for enums and delegates
* MonoType.cs: added serialization support.
* Delegate.cs: added serialization support.
* DBNull.cs: added serialization support.
* UnitySerializationHolder.cs: supports serialization of Assembly, MonoType and DBNull.
* DelegateSerializationHolder.cs: added.

--- NEW FILE: DelegateSerializationHolder.cs ---
// DelegateSerializationHolder.cs
//
// Author:
//  Lluis Sanchez Gual (lsg@ctv.es)
//
// (C) 2003 Lluis Sanchez Gual

using System;
using System.Reflection;
using System.Runtime.Serialization;

namespace System
{
	[Serializable]
	public class DelegateSerializationHolder: ISerializable, IObjectReference
	{
		Delegate _delegate;	// The deserialized delegate

		[Serializable]
		class DelegateEntry
		{
			// A DelegateEntry holds information about a delegate that is part
			// of an invocation list of a multicast delegate.

			public DelegateEntry (Delegate del, string targetLabel)
			{
				type = del.GetType().FullName;
				assembly = del.GetType().Assembly.FullName;
				target = targetLabel;
				targetTypeAssembly = del.Method.DeclaringType.Assembly.FullName;
				targetTypeName = del.Method.DeclaringType.FullName;
				methodName = del.Method.Name;
			}

			public Delegate DeserializeDelegate(SerializationInfo info)
			{
				object realTarget = null;
				if (target != null)
					realTarget = info.GetValue (target.ToString(), typeof(object));

				Assembly dasm = Assembly.Load (assembly);
				Type dt = dasm.GetType (type);

				Delegate del;
				if (realTarget != null)
					del = Delegate.CreateDelegate (dt, realTarget, methodName);
				else
				{
					Assembly tasm = Assembly.Load (targetTypeAssembly);
					Type tt = tasm.GetType (targetTypeName);
					del = Delegate.CreateDelegate (dt, tt, methodName);
				}

				if (!del.Method.IsPublic)
					throw new SerializationException ("Serialization will not deserialize delegates to non-public methods.");

				return del;
			}

			string type;
			string assembly;
			public object target;
			string targetTypeAssembly;
			string targetTypeName;
			string methodName;
			public DelegateEntry delegateEntry;	// next delegate in the invocation list
		}

		DelegateSerializationHolder(SerializationInfo info, StreamingContext ctx)
		{
			DelegateEntry entryChain = (DelegateEntry)info.GetValue ("Delegate", typeof(DelegateEntry));

			// Count the number of delegates to combine

			int count = 0;
			DelegateEntry entry = entryChain;
			while (entry != null)
			{
				entry = entry.delegateEntry;
				count++;
			}

			// Deserializes and combines the delegates

			if (count == 1) 
				_delegate = entryChain.DeserializeDelegate (info);
			else
			{
				Delegate[] delegates = new Delegate[count];
				entry = entryChain;
				for (int n=0; n<count; n++)
				{
					delegates[n] = entry.DeserializeDelegate (info);
					entry = entry.delegateEntry;
				}

				_delegate = Delegate.Combine (delegates);
			}
		}

		public static void GetDelegateData(Delegate instance, SerializationInfo info, StreamingContext ctx)
		{
			// Fills a SerializationInfo object with the information of the delegate.

			Delegate[] delegates = instance.GetInvocationList();
			DelegateEntry lastEntry = null;
			for (int n=0; n<delegates.Length; n++)
			{
				Delegate del = delegates[n];
				string targetLabel = (del.Target != null) ? ("target" + n) : null;
				DelegateEntry entry = new DelegateEntry(del, targetLabel);

				if (lastEntry == null)
					info.AddValue ("Delegate", entry);
				else
					lastEntry.delegateEntry = entry;

				lastEntry = entry;
				if (del.Target != null)
					info.AddValue (targetLabel, del.Target);
			}
			info.SetType (typeof (DelegateSerializationHolder));
		}

		public void GetObjectData(SerializationInfo info, StreamingContext context)
		{
			// Not needed.
			throw new NotSupportedException();
		}

		public object GetRealObject(StreamingContext context)
		{
			return _delegate;
		}
	}
}

--- NEW FILE: UnitySerializationHolder.cs ---
// UnitySerializationHolder.cs
//
// Author:
//  Lluis Sanchez Gual (lsg@ctv.es)
//
// (C) 2003 Lluis Sanchez Gual

using System;
using System.Reflection;
using System.Runtime.Serialization;

namespace System
{
	[Serializable]
	internal class UnitySerializationHolder: IObjectReference, ISerializable
	{
		string _data;
		UnityType _unityType;
		string _assemblyName;

		// FIXME: there must be other types that use UnitySerializationHolder for
		// serialization, but I don't know yet which ones.

		enum UnityType: byte { DBNull = 2, Type = 4, Assembly = 6 }

		UnitySerializationHolder(SerializationInfo info, StreamingContext ctx)
		{
			_data = info.GetString("Data");
			_unityType = (UnityType) info.GetInt32("UnityType");
			_assemblyName = info.GetString("AssemblyName");
		}

		public static void GetTypeData(Type instance, SerializationInfo info, StreamingContext ctx)
		{
			info.AddValue ("Data", instance.FullName);
			info.AddValue ("UnityType", (int) UnityType.Type);
			info.AddValue ("AssemblyName", instance.Assembly.FullName);
			info.SetType (typeof (UnitySerializationHolder));
		}

		public static void GetDBNullData(DBNull instance, SerializationInfo info, StreamingContext ctx)
		{
			info.AddValue ("Data", null);
			info.AddValue ("UnityType", (int) UnityType.DBNull);
			info.AddValue ("AssemblyName", instance.GetType().Assembly.FullName);
			info.SetType (typeof (UnitySerializationHolder));
		}

		public static void GetAssemblyData(Assembly instance, SerializationInfo info, StreamingContext ctx)
		{
			info.AddValue ("Data", instance.FullName);
			info.AddValue ("UnityType", (int) UnityType.Assembly);
			info.AddValue ("AssemblyName", instance.FullName);
			info.SetType (typeof (UnitySerializationHolder));
		}

		public void GetObjectData(SerializationInfo info, StreamingContext context)
		{
			// Not needed.
			throw new NotSupportedException();
		}

		public object GetRealObject(StreamingContext context)
		{
			switch (_unityType)
			{
				case UnityType.Type:
					Assembly assembly = Assembly.Load (_assemblyName);
					return assembly.GetType (_data);

				case UnityType.DBNull:
					return DBNull.Value;

				case UnityType.Assembly:
					return Assembly.Load (_data);

				default:
					throw new NotSupportedException ("UnitySerializationHolder does not support this type");
			}
		}
	}
}

Index: ChangeLog
===================================================================
RCS file: /cvs/public/mcs/class/corlib/System/ChangeLog,v
retrieving revision 1.449
retrieving revision 1.450
diff -u -d -r1.449 -r1.450
--- ChangeLog	12 Jan 2003 08:09:12 -0000	1.449
+++ ChangeLog	17 Jan 2003 14:16:41 -0000	1.450
@@ -1,3 +1,14 @@
+2003-01-16  Lluis Sanchez Gual <lsg@ctv.es>
+
+	* Type.cs: corrected property IsSerializable. It should always return true 
+      for enums and delegates
+    * MonoType.cs: added serialization support.
+    * Delegate.cs: added serialization support.
+    * DBNull.cs: added serialization support.
+    * UnitySerializationHolder.cs: supports serialization of Assembly,
+      MonoType and DBNull.
+    * DelegateSerializationHolder.cs: added.
+
 2003-01-12  Gonzalo Paniagua Javier <gonzalo@ximian.com>
 
 	* Exception.cs: changed default message to match MS one.

Index: DBNull.cs
===================================================================
RCS file: /cvs/public/mcs/class/corlib/System/DBNull.cs,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -d -r1.1 -r1.2
--- DBNull.cs	6 Feb 2002 00:13:57 -0000	1.1
+++ DBNull.cs	17 Jan 2003 14:16:41 -0000	1.2
@@ -20,9 +20,9 @@
 		private DBNull () {}
 
 		// Methods
-		[MonoTODO]
 		public void GetObjectData (SerializationInfo info, StreamingContext context)
 		{
+			UnitySerializationHolder.GetDBNullData (this, info, context);
 		}
 
 		public TypeCode GetTypeCode ()

Index: Delegate.cs
===================================================================
RCS file: /cvs/public/mcs/class/corlib/System/Delegate.cs,v
retrieving revision 1.22
retrieving revision 1.23
diff -u -d -r1.22 -r1.23
--- Delegate.cs	11 Sep 2002 09:08:58 -0000	1.22
+++ Delegate.cs	17 Jan 2003 14:16:41 -0000	1.23
@@ -218,10 +218,9 @@
 		}
 
 		// This is from ISerializable
-		[MonoTODO]
 		public void GetObjectData (SerializationInfo info, StreamingContext context)
 		{
-			// TODO: IMPLEMENT ME
+			DelegateSerializationHolder.GetDelegateData (this, info, context);
 		}
 
 		public virtual Delegate[] GetInvocationList()

Index: MonoType.cs
===================================================================
RCS file: /cvs/public/mcs/class/corlib/System/MonoType.cs,v
retrieving revision 1.37
retrieving revision 1.38
diff -u -d -r1.37 -r1.38
--- MonoType.cs	10 Jan 2003 02:11:16 -0000	1.37
+++ MonoType.cs	17 Jan 2003 14:16:41 -0000	1.38
@@ -11,6 +11,7 @@
 using System.Reflection;
 using System.Runtime.CompilerServices;
 using System.Globalization;
+using System.Runtime.Serialization;
 
 namespace System
 {
@@ -24,7 +25,8 @@
 		public bool isprimitive;
 	}
 
-	internal sealed class MonoType : Type
+	[Serializable]
+	internal sealed class MonoType : Type, ISerializable
 	{
 
 		[MethodImplAttribute(MethodImplOptions.InternalCall)]
@@ -497,10 +499,7 @@
 			get {
 				MonoTypeInfo info;
 				get_type_info (_impl, out info);
-				if (info.nested_in == null)
-					return info.name_space;
-				else
-					return info.nested_in.Namespace;
+				return info.name_space;
 			}
 		}
 
@@ -538,5 +537,10 @@
 			get_type_info (_impl, out info);
 			return info.rank;
 		}
+
+		public void GetObjectData(SerializationInfo info, StreamingContext context)
+		{
+			UnitySerializationHolder.GetTypeData (this, info, context);
+		}
 	}
 }

Index: Type.cs
===================================================================
RCS file: /cvs/public/mcs/class/corlib/System/Type.cs,v
retrieving revision 1.66
retrieving revision 1.67
diff -u -d -r1.66 -r1.67
--- Type.cs	9 Jan 2003 22:21:52 -0000	1.66
+++ Type.cs	17 Jan 2003 14:16:41 -0000	1.67
@@ -289,7 +289,9 @@
 
 		public bool IsSerializable {
 			get {
-				return (Attributes & TypeAttributes.Serializable) != 0;
+				// Enums and delegates are always serializable
+				return (Attributes & TypeAttributes.Serializable) != 0 || IsEnum || 
+					type_is_subtype_of (this, typeof (System.Delegate), false);
 			}
 		}