[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Dotgnu-pnet-commits] CVS: pnetlib/runtime/System DelegateSerializationH
From: |
Rhys Weatherley <address@hidden> |
Subject: |
[Dotgnu-pnet-commits] CVS: pnetlib/runtime/System DelegateSerializationHolder.cs, NONE, 1.1 Delegate.cs, 1.14, 1.15 MulticastDelegate.cs, 1.7, 1.8 |
Date: |
Fri, 22 Aug 2003 20:17:59 -0400 |
Update of /cvsroot/dotgnu-pnet/pnetlib/runtime/System
In directory subversions:/tmp/cvs-serv17410/runtime/System
Modified Files:
Delegate.cs MulticastDelegate.cs
Added Files:
DelegateSerializationHolder.cs
Log Message:
Serialization support for delegates.
--- NEW FILE ---
/*
* DelegateSerializationHolder.cs - Implementation of the
* "System.DelegateSerializationHolder" class.
*
* Copyright (C) 2003 Southern Storm Software, Pty Ltd.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
namespace System
{
#if CONFIG_SERIALIZATION
using System.Runtime.Serialization;
using System.Reflection;
using System.Private;
// This class is used as a proxy to stand in for delegate objects.
// This class must be named "System.DelegateSerializationHolder" for
// compatibility with other serialization implementations.
internal class DelegateSerializationHolder : ISerializable, IObjectReference
{
// Entry class that is used to hold the information about a delegate.
[Serializable]
internal class DelegateEntry
{
public String type;
public String assembly;
public Object target;
public String targetTypeAssembly;
public String targetTypeName;
public String methodName;
public DelegateEntry delegateEntry;
// Convert a delegate serialization entry into a delegate.
public Delegate ToDelegate()
{
Assembly assem;
Type delegateType;
Type targetType;
// Validate the entry state.
if(methodName == null ||
methodName.Length == 0)
{
throw new SerializationException
(_("Serialize_StateMissing"));
}
// Fetch the delegate type.
assem =
FormatterServices.GetAssemblyByName(assembly);
if(assem == null)
{
throw new SerializationException
(_("Serialize_UnknownAssembly"));
}
delegateType = assem.GetType(type);
if(delegateType == null)
{
throw new SerializationException
(_("Serialize_StateMissing"));
}
// Fetch the target type.
assem =
FormatterServices.GetAssemblyByName
(targetTypeAssembly);
if(assem == null)
{
throw new SerializationException
(_("Serialize_UnknownAssembly"));
}
targetType =
assem.GetType(targetTypeName);
if(targetType == null)
{
throw new SerializationException
(_("Serialize_StateMissing"));
}
// Check that the target is an instance
of
// the specified target type.
if(target != null)
{
if(!targetType.IsInstanceOfType(target))
{
throw new
SerializationException
(_("Serialize_DelegateTargetMismatch"));
}
}
// Create the Delegate.
Delegate del;
if(target != null)
{
del = Delegate.CreateDelegate
(delegateType, target,
methodName);
}
else
{
del = Delegate.CreateDelegate
(delegateType,
targetType, methodName);
}
// Fail if the method is non-public.
MethodInfo method = del.Method;
if(method != null && !(method.IsPublic))
{
throw new SerializationException
(_("Serialize_DelegateNotPublic"));
}
return del;
}
}; // class DelegateEntry
// Internal state.
private DelegateEntry entry;
// Constructor.
public DelegateSerializationHolder(SerializationInfo info,
StreamingContext context)
{
if(info == null)
{
throw new ArgumentNullException("info");
}
bool needsResolve = false;
try
{
// Try the new serialization format
first.
entry = (DelegateEntry)(info.GetValue
("Delegate",
typeof(DelegateEntry)));
needsResolve = true;
}
catch(Exception)
{
// Try the old-style serialization
format (deprecated).
entry = new DelegateEntry();
entry.type =
info.GetString("DelegateType");
entry.assembly =
info.GetString("DelegateAssembly");
entry.target = info.GetValue("Target",
typeof(Object));
entry.targetTypeAssembly =
info.GetString("TargetTypeAssembly");
entry.targetTypeName =
info.GetString("TargetTypeName");
entry.methodName =
info.GetString("MethodName");
}
// Resolve targets specified as field names.
if(needsResolve)
{
DelegateEntry e = entry;
while(e != null)
{
if(e.target is String)
{
e.target = info.GetValue
((String)(e.target), typeof(Object));
}
e = e.delegateEntry;
}
}
}
// Serialize a delegate object.
internal static DelegateEntry Serialize
(SerializationInfo info, int listPosition,
Type delegateType, Object target, MethodBase
method)
{
// Create the new delegate entry block.
DelegateEntry entry = new DelegateEntry();
entry.type = delegateType.FullName;
entry.assembly = delegateType.Assembly.FullName;
entry.target = target;
entry.targetTypeAssembly =
method.ReflectedType.Assembly.FullName;
entry.targetTypeName =
method.ReflectedType.FullName;
entry.methodName = method.Name;
// Add the block if this is the first in the
list.
if(info.MemberCount == 0)
{
info.SetType(typeof(DelegateSerializationHolder));
info.AddValue("Delegate", entry,
typeof(DelegateEntry));
}
// Add the target object to the top level of
the info block.
// Needed to get around order of fixup problems
in some
// third party serialization implementations.
if(target != null)
{
String name = "target" +
listPosition.ToString();
info.AddValue(name, target,
typeof(Object));
entry.target = name;
}
// Return the entry to the caller so that we
can chain
// multiple entries together for multicast
delegates.
return entry;
}
// Serialize a multicast delegate object.
internal static void SerializeMulticast
(SerializationInfo info, MulticastDelegate del)
{
DelegateEntry entry, next;
int index = 0;
// Serialize the first entry on the multicast
list.
entry = Serialize(info, index++, del.GetType(),
del.target,
MethodBase.GetMethodFromHandle(del.method));
// Serialize the rest of the multicast chain.
del = del.prev;
while(del != null)
{
next = Serialize
(info, index++, del.GetType(),
del.target,
MethodBase.GetMethodFromHandle(del.method));
entry.delegateEntry = next;
entry = next;
del = del.prev;
}
}
// Implement the ISerializable interface.
public void GetObjectData(SerializationInfo info, StreamingContext
context)
{
// This method should never be called.
throw new NotSupportedException();
}
// Implement the IObjectReference interface.
public Object GetRealObject(StreamingContext context)
{
// Get the first delegate in the chain.
Delegate del = entry.ToDelegate();
// Bail out early if this is a unicast delegate.
if(!(del is MulticastDelegate) ||
entry.delegateEntry == null)
{
return del;
}
// Build the multicast delegate chain.
Delegate end = del;
Delegate newDelegate;
DelegateEntry e = entry.delegateEntry;
while(e != null)
{
newDelegate = e.ToDelegate();
if(newDelegate.GetType() !=
del.GetType())
{
throw new SerializationException
(_("Arg_DelegateMismatch"));
}
((MulticastDelegate)end).prev =
(newDelegate as
MulticastDelegate);
end = newDelegate;
e = e.delegateEntry;
}
return del;
}
}; // class DelegateSerializationHolder
#endif // CONFIG_SERIALIZATION
}; // namespace System
Index: Delegate.cs
===================================================================
RCS file: /cvsroot/dotgnu-pnet/pnetlib/runtime/System/Delegate.cs,v
retrieving revision 1.14
retrieving revision 1.15
diff -C2 -r1.14 -r1.15
*** Delegate.cs 29 May 2003 01:22:40 -0000 1.14
--- Delegate.cs 23 Aug 2003 00:17:57 -0000 1.15
***************
*** 510,520 ****
#if CONFIG_SERIALIZATION
// Get the serialization data for this object.
- [TODO]
public virtual void GetObjectData(SerializationInfo info,
StreamingContext context)
{
! // TODO
}
#endif
--- 510,527 ----
#if CONFIG_SERIALIZATION
+
// Get the serialization data for this object.
public virtual void GetObjectData(SerializationInfo info,
StreamingContext context)
{
! if(info == null)
! {
! throw new ArgumentNullException("info");
! }
! DelegateSerializationHolder.Serialize
! (info, 0, GetType(), target,
!
MethodBase.GetMethodFromHandle(method));
}
+
#endif
Index: MulticastDelegate.cs
===================================================================
RCS file: /cvsroot/dotgnu-pnet/pnetlib/runtime/System/MulticastDelegate.cs,v
retrieving revision 1.7
retrieving revision 1.8
diff -C2 -r1.7 -r1.8
*** MulticastDelegate.cs 26 May 2003 04:41:21 -0000 1.7
--- MulticastDelegate.cs 23 Aug 2003 00:17:57 -0000 1.8
***************
*** 2,6 ****
* MulticastDelegate.cs - Implementation of "System.MulticastDelegate".
*
! * Copyright (C) 2001, 2002 Southern Storm Software, Pty Ltd.
*
* This program is free software; you can redistribute it and/or modify
--- 2,6 ----
* MulticastDelegate.cs - Implementation of "System.MulticastDelegate".
*
! * Copyright (C) 2001, 2002, 2003 Southern Storm Software, Pty Ltd.
*
* This program is free software; you can redistribute it and/or modify
***************
*** 32,36 ****
{
// Previous delegate on the same invocation list.
! private MulticastDelegate prev;
#if CONFIG_REFLECTION
--- 32,36 ----
{
// Previous delegate on the same invocation list.
! internal MulticastDelegate prev;
#if CONFIG_REFLECTION
***************
*** 304,312 ****
// Get serialization data for this delegate.
- [TODO]
public override void GetObjectData
(SerializationInfo info, StreamingContext
context)
{
! // TODO
}
--- 304,315 ----
// Get serialization data for this delegate.
public override void GetObjectData
(SerializationInfo info, StreamingContext
context)
{
! if(info == null)
! {
! throw new ArgumentNullException("info");
! }
!
DelegateSerializationHolder.SerializeMulticast(info, this);
}
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- [Dotgnu-pnet-commits] CVS: pnetlib/runtime/System DelegateSerializationHolder.cs, NONE, 1.1 Delegate.cs, 1.14, 1.15 MulticastDelegate.cs, 1.7, 1.8,
Rhys Weatherley <address@hidden> <=