DelegateSerializationHolder.cs source code in C# .NET

Source code for the .NET framework in C#

                        

Code:

/ 4.0 / 4.0 / DEVDIV_TFS / Dev10 / Releases / RTMRel / ndp / clr / src / BCL / System / DelegateSerializationHolder.cs / 1305376 / DelegateSerializationHolder.cs

                            // ==++== 
//
//   Copyright (c) Microsoft Corporation.  All rights reserved.
//
// ==--== 

    using System; 
    using System.Reflection; 
    using System.Runtime.Remoting;
    using System.Runtime.Serialization; 
using System.Security.Permissions;
using System.Globalization;
using System.Diagnostics.Contracts;
 
namespace System
{ 
    [Serializable] 
    internal sealed class DelegateSerializationHolder : IObjectReference, ISerializable
    { 
        #region Static Members
        [System.Security.SecurityCritical]  // auto-generated
        internal static DelegateEntry GetDelegateSerializationInfo(
            SerializationInfo info, Type delegateType, Object target, MethodInfo method, int targetIndex) 
        {
            // Used for MulticastDelegate 
 
            if (method == null)
                throw new ArgumentNullException("method"); 
            Contract.EndContractBlock();

            if (!method.IsPublic || (method.DeclaringType != null && !method.DeclaringType.IsVisible))
                new ReflectionPermission(ReflectionPermissionFlag.MemberAccess).Demand(); 

            Type c = delegateType.BaseType; 
 
            if (c == null || (c != typeof(Delegate) && c != typeof(MulticastDelegate)))
                throw new ArgumentException(Environment.GetResourceString("Arg_MustBeDelegate"),"type"); 

            if (method.DeclaringType == null)
                throw new NotSupportedException(Environment.GetResourceString("NotSupported_GlobalMethodSerialization"));
 
            DelegateEntry de = new DelegateEntry(delegateType.FullName, delegateType.Module.Assembly.FullName, target,
                method.ReflectedType.Module.Assembly.FullName, method.ReflectedType.FullName, method.Name); 
 
            if (info.MemberCount == 0)
            { 
                info.SetType(typeof(DelegateSerializationHolder));
                info.AddValue("Delegate",de,typeof(DelegateEntry));
            }
 
            // target can be an object so it needs to be added to the info, or else a fixup is needed
            // when deserializing, and the fixup will occur too late. If it is added directly to the 
            // info then the rules of deserialization will guarantee that it will be available when 
            // needed
 
            if (target != null)
            {
                String targetName = "target" + targetIndex;
                info.AddValue(targetName, de.target); 
                de.target = targetName;
            } 
 
            // Due to a number of additions (delegate signature binding relaxation, delegates with open this or closed over the
            // first parameter and delegates over generic methods) we need to send a deal more information than previously. We can 
            // get this by serializing the target MethodInfo. We still need to send the same information as before though (the
            // DelegateEntry above) for backwards compatibility. And we want to send the MethodInfo (which is serialized via an
            // ISerializable holder) as a top-level child of the info for the same reason as the target above -- we wouldn't have an
            // order of deserialization guarantee otherwise. 
            String methodInfoName = "method" + targetIndex;
            info.AddValue(methodInfoName, method); 
 
            return de;
        } 
        #endregion

        #region Definitions
        [Serializable] 
        internal class DelegateEntry
        { 
            #region Internal Data Members 
            internal String type;
            internal String assembly; 
            internal Object target;
            internal String targetTypeAssembly;
            internal String targetTypeName;
            internal String methodName; 
            internal DelegateEntry delegateEntry;
            #endregion 
 
            #region Constructor
            internal DelegateEntry( 
                String type, String assembly, Object target, String targetTypeAssembly, String targetTypeName, String methodName)
            {
                this.type = type;
                this.assembly = assembly; 
                this.target = target;
                this.targetTypeAssembly = targetTypeAssembly; 
                this.targetTypeName = targetTypeName; 
                this.methodName = methodName;
            } 
            #endregion

            #region Internal Members
            internal DelegateEntry Entry 
            {
                get { return delegateEntry; } 
                set { delegateEntry = value; } 
            }
            #endregion 
        }

        #endregion
 
        #region Private Data Members
        private DelegateEntry m_delegateEntry; 
        private MethodInfo[] m_methods; 
        #endregion
 
        #region Constructor
        [System.Security.SecurityCritical]  // auto-generated
        private DelegateSerializationHolder(SerializationInfo info, StreamingContext context)
        { 
            if (info == null)
                throw new ArgumentNullException("info"); 
            Contract.EndContractBlock(); 

            bool bNewWire = true; 

            try
            {
                m_delegateEntry = (DelegateEntry)info.GetValue("Delegate", typeof(DelegateEntry)); 
            }
            catch 
            { 
                // Old wire format
                m_delegateEntry = OldDelegateWireFormat(info, context); 
                bNewWire = false;
            }

            if (bNewWire) 
            {
                // retrieve the targets 
                DelegateEntry deiter = m_delegateEntry; 
                int count = 0;
                while (deiter != null) 
                {
                    if (deiter.target != null)
                    {
                        string stringTarget = deiter.target as string; //need test to pass older wire format 
                        if (stringTarget != null)
                            deiter.target = info.GetValue(stringTarget, typeof(Object)); 
                    } 
                    count++;
                    deiter = deiter.delegateEntry; 
                }

                // If the sender is as recent as us they'll have provided MethodInfos for each delegate. Look for these and pack
                // them into an ordered array if present. 
                MethodInfo[] methods = new MethodInfo[count];
                int i; 
                for (i = 0; i < count; i++) 
                {
                    String methodInfoName = "method" + i; 
                    methods[i] = (MethodInfo)info.GetValueNoThrow(methodInfoName, typeof(MethodInfo));
                    if (methods[i] == null)
                        break;
                } 

                // If we got the info then make the array available for deserialization. 
                if (i == count) 
                    m_methods = methods;
            } 
        }
        #endregion

        #region Private Members 
        private void ThrowInsufficientState(string field)
        { 
            throw new SerializationException( 
                Environment.GetResourceString("Serialization_InsufficientDeserializationState", field));
        } 

        private DelegateEntry OldDelegateWireFormat(SerializationInfo info, StreamingContext context)
        {
            if (info == null) 
                throw new ArgumentNullException("info");
            Contract.EndContractBlock(); 
 
            String delegateType = info.GetString("DelegateType");
            String delegateAssembly = info.GetString("DelegateAssembly"); 
            Object target = info.GetValue("Target", typeof(Object));
            String targetTypeAssembly = info.GetString("TargetTypeAssembly");
            String targetTypeName = info.GetString("TargetTypeName");
            String methodName = info.GetString("MethodName"); 

            return new DelegateEntry(delegateType, delegateAssembly, target, targetTypeAssembly, targetTypeName, methodName); 
        } 

        [System.Security.SecuritySafeCritical]  // auto-generated 
        private Delegate GetDelegate(DelegateEntry de, int index)
        {
            Delegate d;
 
            try
            { 
                if (de.methodName == null || de.methodName.Length == 0) 
                    ThrowInsufficientState("MethodName");
 
                if (de.assembly == null || de.assembly.Length == 0)
                    ThrowInsufficientState("DelegateAssembly");

                if (de.targetTypeName == null || de.targetTypeName.Length == 0) 
                    ThrowInsufficientState("TargetTypeName");
 
                RuntimeType type = (RuntimeType)Assembly.Load(de.assembly).GetType(de.type, true, false); 
                RuntimeType targetType = (RuntimeType)Assembly.Load(de.targetTypeAssembly).GetType(de.targetTypeName, true, false);
 
                // If we received the new style delegate encoding we already have the target MethodInfo in hand.
                if (m_methods != null)
                {
#if FEATURE_REMOTING 
                    Object target = de.target != null ? RemotingServices.CheckCast(de.target, targetType) : null;
#else 
                    if(!targetType.IsInstanceOfType(de.target)) 
                        throw new InvalidCastException();
                    Contract.EndContractBlock(); 
                    Object target=de.target;
#endif
                    d = Delegate.InternalCreateDelegate(type, target, m_methods[index]);
                } 
                else
                { 
                    if (de.target != null) 
#if FEATURE_REMOTING
                        d = Delegate.CreateDelegate(type, RemotingServices.CheckCast(de.target, targetType), de.methodName); 
#else
                {
                    if(!targetType.IsInstanceOfType(de.target))
                        throw new InvalidCastException(); 
                     d = Delegate.CreateDelegate(type, de.target, de.methodName);
                } 
#endif 
                    else
                        d = Delegate.CreateDelegate(type, targetType, de.methodName); 
                }

                if ((d.Method != null && !d.Method.IsPublic) || (d.Method.DeclaringType != null && !d.Method.DeclaringType.IsVisible))
                    new ReflectionPermission(ReflectionPermissionFlag.MemberAccess).Demand(); 
            }
            catch (Exception e) 
            { 
                if (e is SerializationException)
                    throw e; 

                throw new SerializationException(e.Message, e);
            }
 
            return d;
        } 
        #endregion 

        #region IObjectReference 
        [System.Security.SecurityCritical]  // auto-generated
        public Object GetRealObject(StreamingContext context)
        {
            int count = 0; 
            for (DelegateEntry de = m_delegateEntry; de != null; de = de.Entry)
                count++; 
 
            int maxindex = count - 1;
 
            if (count == 1)
            {
                return GetDelegate(m_delegateEntry, 0);
            } 
            else
            { 
                object[] invocationList = new object[count]; 

                for (DelegateEntry de = m_delegateEntry; de != null; de = de.Entry) 
                {
                    // Be careful to match the index we pass to GetDelegate (used to look up extra information for each delegate) to
                    // the order we process the entries: we're actually looking at them in reverse order.
                    --count; 
                    invocationList[count] = GetDelegate(de, maxindex - count);
                } 
                return ((MulticastDelegate)invocationList[0]).NewMulticastDelegate(invocationList, invocationList.Length); 
            }
        } 
        #endregion

        #region ISerializable
        [System.Security.SecurityCritical]  // auto-generated 
        public void GetObjectData(SerializationInfo info, StreamingContext context)
        { 
            throw new NotSupportedException(Environment.GetResourceString("NotSupported_DelegateSerHolderSerial")); 
        }
        #endregion 
    }
}

 

 
 

 



 

 
 

 



 

 
 


// File provided for Reference Use Only by Microsoft Corporation (c) 2007.
// ==++== 
//
//   Copyright (c) Microsoft Corporation.  All rights reserved.
//
// ==--== 

    using System; 
    using System.Reflection; 
    using System.Runtime.Remoting;
    using System.Runtime.Serialization; 
using System.Security.Permissions;
using System.Globalization;
using System.Diagnostics.Contracts;
 
namespace System
{ 
    [Serializable] 
    internal sealed class DelegateSerializationHolder : IObjectReference, ISerializable
    { 
        #region Static Members
        [System.Security.SecurityCritical]  // auto-generated
        internal static DelegateEntry GetDelegateSerializationInfo(
            SerializationInfo info, Type delegateType, Object target, MethodInfo method, int targetIndex) 
        {
            // Used for MulticastDelegate 
 
            if (method == null)
                throw new ArgumentNullException("method"); 
            Contract.EndContractBlock();

            if (!method.IsPublic || (method.DeclaringType != null && !method.DeclaringType.IsVisible))
                new ReflectionPermission(ReflectionPermissionFlag.MemberAccess).Demand(); 

            Type c = delegateType.BaseType; 
 
            if (c == null || (c != typeof(Delegate) && c != typeof(MulticastDelegate)))
                throw new ArgumentException(Environment.GetResourceString("Arg_MustBeDelegate"),"type"); 

            if (method.DeclaringType == null)
                throw new NotSupportedException(Environment.GetResourceString("NotSupported_GlobalMethodSerialization"));
 
            DelegateEntry de = new DelegateEntry(delegateType.FullName, delegateType.Module.Assembly.FullName, target,
                method.ReflectedType.Module.Assembly.FullName, method.ReflectedType.FullName, method.Name); 
 
            if (info.MemberCount == 0)
            { 
                info.SetType(typeof(DelegateSerializationHolder));
                info.AddValue("Delegate",de,typeof(DelegateEntry));
            }
 
            // target can be an object so it needs to be added to the info, or else a fixup is needed
            // when deserializing, and the fixup will occur too late. If it is added directly to the 
            // info then the rules of deserialization will guarantee that it will be available when 
            // needed
 
            if (target != null)
            {
                String targetName = "target" + targetIndex;
                info.AddValue(targetName, de.target); 
                de.target = targetName;
            } 
 
            // Due to a number of additions (delegate signature binding relaxation, delegates with open this or closed over the
            // first parameter and delegates over generic methods) we need to send a deal more information than previously. We can 
            // get this by serializing the target MethodInfo. We still need to send the same information as before though (the
            // DelegateEntry above) for backwards compatibility. And we want to send the MethodInfo (which is serialized via an
            // ISerializable holder) as a top-level child of the info for the same reason as the target above -- we wouldn't have an
            // order of deserialization guarantee otherwise. 
            String methodInfoName = "method" + targetIndex;
            info.AddValue(methodInfoName, method); 
 
            return de;
        } 
        #endregion

        #region Definitions
        [Serializable] 
        internal class DelegateEntry
        { 
            #region Internal Data Members 
            internal String type;
            internal String assembly; 
            internal Object target;
            internal String targetTypeAssembly;
            internal String targetTypeName;
            internal String methodName; 
            internal DelegateEntry delegateEntry;
            #endregion 
 
            #region Constructor
            internal DelegateEntry( 
                String type, String assembly, Object target, String targetTypeAssembly, String targetTypeName, String methodName)
            {
                this.type = type;
                this.assembly = assembly; 
                this.target = target;
                this.targetTypeAssembly = targetTypeAssembly; 
                this.targetTypeName = targetTypeName; 
                this.methodName = methodName;
            } 
            #endregion

            #region Internal Members
            internal DelegateEntry Entry 
            {
                get { return delegateEntry; } 
                set { delegateEntry = value; } 
            }
            #endregion 
        }

        #endregion
 
        #region Private Data Members
        private DelegateEntry m_delegateEntry; 
        private MethodInfo[] m_methods; 
        #endregion
 
        #region Constructor
        [System.Security.SecurityCritical]  // auto-generated
        private DelegateSerializationHolder(SerializationInfo info, StreamingContext context)
        { 
            if (info == null)
                throw new ArgumentNullException("info"); 
            Contract.EndContractBlock(); 

            bool bNewWire = true; 

            try
            {
                m_delegateEntry = (DelegateEntry)info.GetValue("Delegate", typeof(DelegateEntry)); 
            }
            catch 
            { 
                // Old wire format
                m_delegateEntry = OldDelegateWireFormat(info, context); 
                bNewWire = false;
            }

            if (bNewWire) 
            {
                // retrieve the targets 
                DelegateEntry deiter = m_delegateEntry; 
                int count = 0;
                while (deiter != null) 
                {
                    if (deiter.target != null)
                    {
                        string stringTarget = deiter.target as string; //need test to pass older wire format 
                        if (stringTarget != null)
                            deiter.target = info.GetValue(stringTarget, typeof(Object)); 
                    } 
                    count++;
                    deiter = deiter.delegateEntry; 
                }

                // If the sender is as recent as us they'll have provided MethodInfos for each delegate. Look for these and pack
                // them into an ordered array if present. 
                MethodInfo[] methods = new MethodInfo[count];
                int i; 
                for (i = 0; i < count; i++) 
                {
                    String methodInfoName = "method" + i; 
                    methods[i] = (MethodInfo)info.GetValueNoThrow(methodInfoName, typeof(MethodInfo));
                    if (methods[i] == null)
                        break;
                } 

                // If we got the info then make the array available for deserialization. 
                if (i == count) 
                    m_methods = methods;
            } 
        }
        #endregion

        #region Private Members 
        private void ThrowInsufficientState(string field)
        { 
            throw new SerializationException( 
                Environment.GetResourceString("Serialization_InsufficientDeserializationState", field));
        } 

        private DelegateEntry OldDelegateWireFormat(SerializationInfo info, StreamingContext context)
        {
            if (info == null) 
                throw new ArgumentNullException("info");
            Contract.EndContractBlock(); 
 
            String delegateType = info.GetString("DelegateType");
            String delegateAssembly = info.GetString("DelegateAssembly"); 
            Object target = info.GetValue("Target", typeof(Object));
            String targetTypeAssembly = info.GetString("TargetTypeAssembly");
            String targetTypeName = info.GetString("TargetTypeName");
            String methodName = info.GetString("MethodName"); 

            return new DelegateEntry(delegateType, delegateAssembly, target, targetTypeAssembly, targetTypeName, methodName); 
        } 

        [System.Security.SecuritySafeCritical]  // auto-generated 
        private Delegate GetDelegate(DelegateEntry de, int index)
        {
            Delegate d;
 
            try
            { 
                if (de.methodName == null || de.methodName.Length == 0) 
                    ThrowInsufficientState("MethodName");
 
                if (de.assembly == null || de.assembly.Length == 0)
                    ThrowInsufficientState("DelegateAssembly");

                if (de.targetTypeName == null || de.targetTypeName.Length == 0) 
                    ThrowInsufficientState("TargetTypeName");
 
                RuntimeType type = (RuntimeType)Assembly.Load(de.assembly).GetType(de.type, true, false); 
                RuntimeType targetType = (RuntimeType)Assembly.Load(de.targetTypeAssembly).GetType(de.targetTypeName, true, false);
 
                // If we received the new style delegate encoding we already have the target MethodInfo in hand.
                if (m_methods != null)
                {
#if FEATURE_REMOTING 
                    Object target = de.target != null ? RemotingServices.CheckCast(de.target, targetType) : null;
#else 
                    if(!targetType.IsInstanceOfType(de.target)) 
                        throw new InvalidCastException();
                    Contract.EndContractBlock(); 
                    Object target=de.target;
#endif
                    d = Delegate.InternalCreateDelegate(type, target, m_methods[index]);
                } 
                else
                { 
                    if (de.target != null) 
#if FEATURE_REMOTING
                        d = Delegate.CreateDelegate(type, RemotingServices.CheckCast(de.target, targetType), de.methodName); 
#else
                {
                    if(!targetType.IsInstanceOfType(de.target))
                        throw new InvalidCastException(); 
                     d = Delegate.CreateDelegate(type, de.target, de.methodName);
                } 
#endif 
                    else
                        d = Delegate.CreateDelegate(type, targetType, de.methodName); 
                }

                if ((d.Method != null && !d.Method.IsPublic) || (d.Method.DeclaringType != null && !d.Method.DeclaringType.IsVisible))
                    new ReflectionPermission(ReflectionPermissionFlag.MemberAccess).Demand(); 
            }
            catch (Exception e) 
            { 
                if (e is SerializationException)
                    throw e; 

                throw new SerializationException(e.Message, e);
            }
 
            return d;
        } 
        #endregion 

        #region IObjectReference 
        [System.Security.SecurityCritical]  // auto-generated
        public Object GetRealObject(StreamingContext context)
        {
            int count = 0; 
            for (DelegateEntry de = m_delegateEntry; de != null; de = de.Entry)
                count++; 
 
            int maxindex = count - 1;
 
            if (count == 1)
            {
                return GetDelegate(m_delegateEntry, 0);
            } 
            else
            { 
                object[] invocationList = new object[count]; 

                for (DelegateEntry de = m_delegateEntry; de != null; de = de.Entry) 
                {
                    // Be careful to match the index we pass to GetDelegate (used to look up extra information for each delegate) to
                    // the order we process the entries: we're actually looking at them in reverse order.
                    --count; 
                    invocationList[count] = GetDelegate(de, maxindex - count);
                } 
                return ((MulticastDelegate)invocationList[0]).NewMulticastDelegate(invocationList, invocationList.Length); 
            }
        } 
        #endregion

        #region ISerializable
        [System.Security.SecurityCritical]  // auto-generated 
        public void GetObjectData(SerializationInfo info, StreamingContext context)
        { 
            throw new NotSupportedException(Environment.GetResourceString("NotSupported_DelegateSerHolderSerial")); 
        }
        #endregion 
    }
}

 

 
 

 



 

 
 

 



 

 
 


// File provided for Reference Use Only by Microsoft Corporation (c) 2007.
                        

Link Menu

Network programming in C#, Network Programming in VB.NET, Network Programming in .NET
This book is available now!
Buy at Amazon US or
Buy at Amazon UK