LogicalMethodInfo.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 / fx / src / Services / Web / System / Web / Services / Protocols / LogicalMethodInfo.cs / 1305376 / LogicalMethodInfo.cs

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

namespace System.Web.Services.Protocols { 
 
    using System;
    using System.Web.Services; 
    using System.Reflection;
    using System.Collections;
    using System.Security.Permissions;
    using System.Globalization; 
    using System.Text;
    using System.Security.Cryptography; 
 
    /// 
    ///  
    ///    [To be supplied.]
    /// 
    public enum LogicalMethodTypes {
        ///  
        /// 
        ///    [To be supplied.] 
        ///  
        [....] = 0x1,
        ///  
        /// 
        ///    [To be supplied.]
        /// 
        Async = 0x2, 
    }
 
 
    /// 
    ///  
    ///    [To be supplied.]
    /// 
    public sealed class LogicalMethodInfo {
        MethodInfo methodInfo; 
        MethodInfo endMethodInfo;
        ParameterInfo[] inParams; 
        ParameterInfo[] outParams; 
        ParameterInfo[] parameters;
        Hashtable attributes; 
        Type retType;
        ParameterInfo callbackParam;
        ParameterInfo stateParam;
        ParameterInfo resultParam; 
        string methodName;
        bool isVoid; 
        static object[] emptyObjectArray = new object[0]; 
        WebServiceBindingAttribute binding;
        WebMethodAttribute attribute; 
        MethodInfo declaration;
        static HashAlgorithm hash;

        ///  
        /// 
        ///    [To be supplied.] 
        ///  
        public LogicalMethodInfo(MethodInfo methodInfo) : this (methodInfo, null) {
        } 

        internal LogicalMethodInfo(MethodInfo methodInfo, WebMethod webMethod) {
            if (methodInfo.IsStatic) throw new InvalidOperationException(Res.GetString(Res.WebMethodStatic, methodInfo.Name));
            this.methodInfo = methodInfo; 
            if (webMethod != null) {
                this.binding = webMethod.binding; 
                this.attribute = webMethod.attribute; 
                this.declaration = webMethod.declaration;
            } 

            MethodInfo methodDefinition = declaration != null ? declaration : methodInfo;
            parameters = methodDefinition.GetParameters();
            inParams = GetInParameters(methodDefinition, parameters, 0, parameters.Length, false); 
            outParams = GetOutParameters(methodDefinition, parameters, 0, parameters.Length, false);
            retType = methodDefinition.ReturnType; 
            isVoid = retType == typeof(void); 
            methodName = methodDefinition.Name;
            attributes = new Hashtable(); 
        }

        LogicalMethodInfo(MethodInfo beginMethodInfo, MethodInfo endMethodInfo, WebMethod webMethod) {
            this.methodInfo = beginMethodInfo; 
            this.endMethodInfo = endMethodInfo;
            methodName = beginMethodInfo.Name.Substring(5); 
            if (webMethod != null) { 
                this.binding = webMethod.binding;
                this.attribute = webMethod.attribute; 
                this.declaration = webMethod.declaration;
            }
            ParameterInfo[] beginParamInfos = beginMethodInfo.GetParameters();
            if (beginParamInfos.Length < 2 || 
                beginParamInfos[beginParamInfos.Length - 1].ParameterType != typeof(object) ||
                beginParamInfos[beginParamInfos.Length - 2].ParameterType != typeof(AsyncCallback)) { 
                throw new InvalidOperationException(Res.GetString(Res.WebMethodMissingParams, beginMethodInfo.DeclaringType.FullName, beginMethodInfo.Name, 
                    typeof(AsyncCallback).FullName, typeof(object).FullName));
            } 

            stateParam = beginParamInfos[beginParamInfos.Length - 1];
            callbackParam = beginParamInfos[beginParamInfos.Length - 2];
 
            inParams = GetInParameters(beginMethodInfo, beginParamInfos, 0, beginParamInfos.Length - 2, true);
 
            ParameterInfo[] endParamInfos = endMethodInfo.GetParameters(); 
            resultParam = endParamInfos[0];
            outParams = GetOutParameters(endMethodInfo, endParamInfos, 1, endParamInfos.Length - 1, true); 

            parameters = new ParameterInfo[inParams.Length + outParams.Length];
            inParams.CopyTo(parameters, 0);
            outParams.CopyTo(parameters, inParams.Length); 

            retType = endMethodInfo.ReturnType; 
            isVoid = retType == typeof(void); 
            attributes = new Hashtable();
        } 

        /// 
        /// 
        ///    [To be supplied.] 
        /// 
        public override string ToString() { 
            return methodInfo.ToString(); 
        }
 
        // This takes in parameters, and returns return value followed by out parameters in an array
        /// 
        /// 
        ///    [To be supplied.] 
        /// 
        [PermissionSet(SecurityAction.LinkDemand, Name="FullTrust")] 
        public object[] Invoke(object target, object[] values) { 
            if (outParams.Length > 0) {
                object[] newValues = new object[parameters.Length]; 
                for (int i = 0; i < inParams.Length; i++) {
                    newValues[inParams[i].Position] = values[i];
                }
                values = newValues; 
            }
            object returnValue = methodInfo.Invoke(target, values); 
            if (outParams.Length > 0) { 
                int count = outParams.Length;
                if (!isVoid) count++; 
                object[] results = new object[count];
                count = 0;
                if (!isVoid) results[count++] = returnValue;
                for (int i = 0; i < outParams.Length; i++) { 
                    results[count++] = values[outParams[i].Position];
                } 
                return results; 
            }
            else if (isVoid) { 
                return emptyObjectArray;
            }
            else {
                return new object[] { returnValue }; 
            }
        } 
 
        /// 
        ///  
        ///    [To be supplied.]
        /// 
        [PermissionSet(SecurityAction.LinkDemand, Name="FullTrust")]
        public IAsyncResult BeginInvoke(object target, object[] values, AsyncCallback callback, object asyncState) { 
            object[] asyncValues = new object[values.Length + 2];
            values.CopyTo(asyncValues, 0); 
            asyncValues[values.Length] = callback; 
            asyncValues[values.Length + 1] = asyncState;
            return (IAsyncResult)methodInfo.Invoke(target, asyncValues); 
        }

        /// 
        ///  
        ///    [To be supplied.]
        ///  
        [PermissionSet(SecurityAction.LinkDemand, Name="FullTrust")] 
        public object[] EndInvoke(object target, IAsyncResult asyncResult) {
            object[] values = new object[outParams.Length + 1]; 
            values[0] = asyncResult;
            object returnValue = endMethodInfo.Invoke(target, values);
            if (!isVoid) {
                values[0] = returnValue; 
                return values;
            } 
            else if (outParams.Length > 0) { 
                object[] newValues = new object[outParams.Length];
                Array.Copy(values, 1, newValues, 0, newValues.Length); 
                return newValues;
            }
            else {
                return emptyObjectArray; 
            }
        } 
 
        internal WebServiceBindingAttribute Binding {
            get { return binding; } 
        }

        internal MethodInfo Declaration {
            get { return declaration; } 
        }
 
        ///  
        /// 
        ///    [To be supplied.] 
        /// 
        public Type DeclaringType {
            get { return methodInfo.DeclaringType; }
        } 

        ///  
        ///  
        ///    [To be supplied.]
        ///  
        public string Name {
            get { return methodName; }
        }
 
        /// 
        ///  
        ///    [To be supplied.] 
        /// 
        public ParameterInfo AsyncResultParameter { 
            get { return resultParam; }
        }

        ///  
        /// 
        ///    [To be supplied.] 
        ///  
        public ParameterInfo AsyncCallbackParameter {
            get { return callbackParam; } 
        }

        /// 
        ///  
        ///    [To be supplied.]
        ///  
        public ParameterInfo AsyncStateParameter { 
            get { return stateParam; }
        } 

        /// 
        /// 
        ///    [To be supplied.] 
        /// 
        public Type ReturnType { 
            get { return retType; } 
        }
 
        /// 
        /// 
        ///    [To be supplied.]
        ///  
        public bool IsVoid {
            get { return isVoid; } 
        } 

        ///  
        /// 
        ///    [To be supplied.]
        /// 
        public bool IsAsync { 
            get { return endMethodInfo != null; }
        } 
 
        /// 
        ///  
        ///    [To be supplied.]
        /// 
        public ParameterInfo[] InParameters {
            get { return inParams; } 
        }
 
        ///  
        /// 
        ///    [To be supplied.] 
        /// 
        public ParameterInfo[] OutParameters {
            get { return outParams; }
        } 

        ///  
        ///  
        ///    [To be supplied.]
        ///  
        public ParameterInfo[] Parameters {
            get { return parameters; }
        }
 
        /// 
        ///  
        ///    [To be supplied.] 
        /// 
        public object[] GetCustomAttributes(Type type) { 
            object[] attrForType = null;
            attrForType = (object[])attributes[type];
            if (attrForType != null)
                return attrForType; 
            lock (attributes) {
                attrForType = (object[])attributes[type]; 
                if (attrForType == null){ 
                    if (declaration != null) {
                        object[] declAttributes = declaration.GetCustomAttributes(type, false); 
                        object[] implAttributes = methodInfo.GetCustomAttributes(type, false);
                        if (implAttributes.Length > 0) {
                            if (CanMerge(type)) {
                                ArrayList all = new ArrayList(); 
                                for (int i = 0; i < declAttributes.Length; i++) {
                                    all.Add(declAttributes[i]); 
                                } 
                                for (int i = 0; i < implAttributes.Length; i++) {
                                    all.Add(implAttributes[i]); 
                                }
                                attrForType = (object[])all.ToArray(type);
                            }
                            else { 
                                throw new InvalidOperationException(Res.GetString(Res.ContractOverride, methodInfo.Name, methodInfo.DeclaringType.FullName, declaration.DeclaringType.FullName, declaration.ToString(), implAttributes[0].ToString()));
                            } 
                        } 
                        else {
                            attrForType = declAttributes; 
                        }
                    }
                    else {
                        attrForType = methodInfo.GetCustomAttributes(type, false); 
                    }
                    attributes[type] = attrForType; 
                } 
            }
            return attrForType; 
        }


        ///  
        /// 
        ///    [To be supplied.] 
        ///  
        public object GetCustomAttribute(Type type) {
            object[] attrs = GetCustomAttributes(type); 
            if (attrs.Length == 0) return null;
            return attrs[0];
        }
 
        internal WebMethodAttribute MethodAttribute {
            get { 
                if (attribute == null) { 
                    attribute = (WebMethodAttribute)GetCustomAttribute(typeof(WebMethodAttribute));
                    if (attribute == null) { 
                        attribute = new WebMethodAttribute();
                    }
                }
                return attribute; 
            }
        } 
 
        /// 
        ///  
        ///    [To be supplied.]
        /// 
        public ICustomAttributeProvider CustomAttributeProvider {
            // Custom attributes are always on the XXX ([....]) or BeginXXX (async) method. 
            get { return methodInfo; }
        } 
 
        /// 
        ///  
        ///    [To be supplied.]
        /// 
        public ICustomAttributeProvider ReturnTypeCustomAttributeProvider {
            get { 
                if (declaration != null)
                    return declaration.ReturnTypeCustomAttributes; 
                return methodInfo.ReturnTypeCustomAttributes; 
            }
        } 

        // Do not use this to property get custom attributes.  Instead use the CustomAttributeProvider
        // property which automatically handles where the custom attributes belong for async methods
        // (which are actually two methods: BeginXXX and EndXXX). 
        /// 
        ///  
        ///    [To be supplied.] 
        /// 
        public MethodInfo MethodInfo { 
            get { return endMethodInfo == null ? methodInfo : null; }
        }

        ///  
        /// 
        ///    [To be supplied.] 
        ///  
        public MethodInfo BeginMethodInfo {
            get { return methodInfo; } 
        }

        /// 
        ///  
        ///    [To be supplied.]
        ///  
        public MethodInfo EndMethodInfo { 
            get { return endMethodInfo; }
        } 

        static ParameterInfo[] GetInParameters(MethodInfo methodInfo, ParameterInfo[] paramInfos, int start, int length, bool mustBeIn) {
            int count = 0;
            for (int i = 0; i < length; i++) { 
                ParameterInfo paramInfo = paramInfos[i + start];
                if (IsInParameter(paramInfo)) { 
                    count++; 
                }
                else if (mustBeIn) { 
                    throw new InvalidOperationException(Res.GetString(Res.WebBadOutParameter, paramInfo.Name, methodInfo.DeclaringType.FullName,  paramInfo.Name));
                }
            }
 
            ParameterInfo[] ins = new ParameterInfo[count];
            count = 0; 
            for (int i = 0; i < length; i++) { 
                ParameterInfo paramInfo = paramInfos[i + start];
                if (IsInParameter(paramInfo)) { 
                    ins[count++] = paramInfo;
                }
            }
            return ins; 
        }
 
        static ParameterInfo[] GetOutParameters(MethodInfo methodInfo, ParameterInfo[] paramInfos, int start, int length, bool mustBeOut) { 
            int count = 0;
            for (int i = 0; i < length; i++) { 
                ParameterInfo paramInfo = paramInfos[i + start];
                if (IsOutParameter(paramInfo)) {
                    count++;
                } 
                else if (mustBeOut) {
                    throw new InvalidOperationException(Res.GetString(Res.WebInOutParameter, paramInfo.Name, methodInfo.DeclaringType.FullName,  paramInfo.Name)); 
                } 
            }
 
            ParameterInfo[] outs = new ParameterInfo[count];
            count = 0;
            for (int i = 0; i < length; i++) {
                ParameterInfo paramInfo = paramInfos[i + start]; 
                if (IsOutParameter(paramInfo)) {
                    outs[count++] = paramInfo; 
                } 
            }
            return outs; 
        }

        static bool IsInParameter(ParameterInfo paramInfo) {
            return !paramInfo.IsOut; 
        }
 
        static bool IsOutParameter(ParameterInfo paramInfo) { 
            return paramInfo.IsOut || paramInfo.ParameterType.IsByRef;
        } 

        /// 
        /// 
        ///    [To be supplied.] 
        /// 
        public static bool IsBeginMethod(MethodInfo methodInfo) { 
            return typeof(IAsyncResult).IsAssignableFrom(methodInfo.ReturnType) && 
                methodInfo.Name.StartsWith("Begin", StringComparison.Ordinal);
        } 

        /// 
        /// 
        ///    [To be supplied.] 
        /// 
        public static bool IsEndMethod(MethodInfo methodInfo) { 
            ParameterInfo[] paramInfos = methodInfo.GetParameters(); 
            return paramInfos.Length > 0 &&
                typeof(IAsyncResult).IsAssignableFrom(paramInfos[0].ParameterType) && 
                methodInfo.Name.StartsWith("End", StringComparison.Ordinal);
        }

        ///  
        /// 
        ///    [To be supplied.] 
        ///  
        public static LogicalMethodInfo[] Create(MethodInfo[] methodInfos) {
            return Create(methodInfos, LogicalMethodTypes.Async | LogicalMethodTypes.[....], null); 
        }


        ///  
        /// 
        ///    [To be supplied.] 
        ///  
        public static LogicalMethodInfo[] Create(MethodInfo[] methodInfos, LogicalMethodTypes types) {
            return Create(methodInfos, types, null); 
        }

        internal static LogicalMethodInfo[] Create(MethodInfo[] methodInfos, LogicalMethodTypes types, Hashtable declarations) {
            ArrayList begins = (types & LogicalMethodTypes.Async) != 0 ? new ArrayList() : null; 
            Hashtable ends = (types & LogicalMethodTypes.Async) != 0 ? new Hashtable() : null;
            ArrayList syncs = (types & LogicalMethodTypes.[....]) != 0 ? new ArrayList() : null; 
 
            for (int i = 0; i < methodInfos.Length; i++) {
                MethodInfo methodInfo = methodInfos[i]; 
                if (IsBeginMethod(methodInfo)) {
                    if (begins != null) begins.Add(methodInfo);
                }
                else if (IsEndMethod(methodInfo)) { 
                    if (ends != null) ends.Add(methodInfo.Name, methodInfo);
                } 
                else { 
                    if (syncs != null) syncs.Add(methodInfo);
                } 
            }

            int beginsCount = begins == null ? 0 : begins.Count;
            int syncsCount = syncs == null ? 0 : syncs.Count; 
            int count = syncsCount + beginsCount;
            LogicalMethodInfo[] methods = new LogicalMethodInfo[count]; 
            count = 0; 
            for (int i = 0; i < syncsCount; i++) {
                MethodInfo syncMethod = (MethodInfo)syncs[i]; 
                WebMethod webMethod = declarations == null ? null : (WebMethod)declarations[syncMethod];
                methods[count] = new LogicalMethodInfo(syncMethod, webMethod);
                methods[count].CheckContractOverride();
                count++; 
            }
            for (int i = 0; i < beginsCount; i++) { 
                MethodInfo beginMethodInfo = (MethodInfo)begins[i]; 
                string endName = "End" + beginMethodInfo.Name.Substring(5);
                MethodInfo endMethodInfo = (MethodInfo)ends[endName]; 
                if (endMethodInfo == null) {
                    throw new InvalidOperationException(Res.GetString(Res.WebAsyncMissingEnd, beginMethodInfo.DeclaringType.FullName, beginMethodInfo.Name, endName));
                }
                WebMethod webMethod = declarations == null ? null : (WebMethod)declarations[beginMethodInfo]; 
                methods[count++] = new LogicalMethodInfo(beginMethodInfo, endMethodInfo, webMethod);
            } 
 
            return methods;
        } 

        internal static HashAlgorithm HashAlgorithm {
            get {
                if (hash == null) { 
                    hash = SHA1.Create();
                } 
                return hash; 
            }
        } 

        internal string GetKey() {
            if (methodInfo == null)
                return string.Empty; 
            string key = methodInfo.DeclaringType.FullName + ":" + methodInfo.ToString();
            // for very long method signatures use a hash string instead of actual method signature. 
            if (key.Length > 1024) { 
                byte[] bytes = HashAlgorithm.ComputeHash(Encoding.UTF8.GetBytes(key));
                key = Convert.ToBase64String(bytes); 
            }
            return key;
        }
 
        internal void CheckContractOverride() {
            if (declaration == null) 
                return; 
            methodInfo.GetParameters();
            ParameterInfo[] parameters = methodInfo.GetParameters(); 
            foreach (ParameterInfo p in parameters) {
                object[] attrs = p.GetCustomAttributes(false);
                foreach (object o in attrs) {
                    if (o.GetType().Namespace == "System.Xml.Serialization") { 
                        throw new InvalidOperationException(Res.GetString(Res.ContractOverride, methodInfo.Name, methodInfo.DeclaringType.FullName, declaration.DeclaringType.FullName, declaration.ToString(), o.ToString()));
                    } 
                } 
            }
        } 

        internal static bool CanMerge(Type type) {
            if (type == typeof(SoapHeaderAttribute))
                return true; 
            if (typeof(SoapExtensionAttribute).IsAssignableFrom(type))
                return true; 
            return false; 
        }
    } 
}

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

namespace System.Web.Services.Protocols { 
 
    using System;
    using System.Web.Services; 
    using System.Reflection;
    using System.Collections;
    using System.Security.Permissions;
    using System.Globalization; 
    using System.Text;
    using System.Security.Cryptography; 
 
    /// 
    ///  
    ///    [To be supplied.]
    /// 
    public enum LogicalMethodTypes {
        ///  
        /// 
        ///    [To be supplied.] 
        ///  
        [....] = 0x1,
        ///  
        /// 
        ///    [To be supplied.]
        /// 
        Async = 0x2, 
    }
 
 
    /// 
    ///  
    ///    [To be supplied.]
    /// 
    public sealed class LogicalMethodInfo {
        MethodInfo methodInfo; 
        MethodInfo endMethodInfo;
        ParameterInfo[] inParams; 
        ParameterInfo[] outParams; 
        ParameterInfo[] parameters;
        Hashtable attributes; 
        Type retType;
        ParameterInfo callbackParam;
        ParameterInfo stateParam;
        ParameterInfo resultParam; 
        string methodName;
        bool isVoid; 
        static object[] emptyObjectArray = new object[0]; 
        WebServiceBindingAttribute binding;
        WebMethodAttribute attribute; 
        MethodInfo declaration;
        static HashAlgorithm hash;

        ///  
        /// 
        ///    [To be supplied.] 
        ///  
        public LogicalMethodInfo(MethodInfo methodInfo) : this (methodInfo, null) {
        } 

        internal LogicalMethodInfo(MethodInfo methodInfo, WebMethod webMethod) {
            if (methodInfo.IsStatic) throw new InvalidOperationException(Res.GetString(Res.WebMethodStatic, methodInfo.Name));
            this.methodInfo = methodInfo; 
            if (webMethod != null) {
                this.binding = webMethod.binding; 
                this.attribute = webMethod.attribute; 
                this.declaration = webMethod.declaration;
            } 

            MethodInfo methodDefinition = declaration != null ? declaration : methodInfo;
            parameters = methodDefinition.GetParameters();
            inParams = GetInParameters(methodDefinition, parameters, 0, parameters.Length, false); 
            outParams = GetOutParameters(methodDefinition, parameters, 0, parameters.Length, false);
            retType = methodDefinition.ReturnType; 
            isVoid = retType == typeof(void); 
            methodName = methodDefinition.Name;
            attributes = new Hashtable(); 
        }

        LogicalMethodInfo(MethodInfo beginMethodInfo, MethodInfo endMethodInfo, WebMethod webMethod) {
            this.methodInfo = beginMethodInfo; 
            this.endMethodInfo = endMethodInfo;
            methodName = beginMethodInfo.Name.Substring(5); 
            if (webMethod != null) { 
                this.binding = webMethod.binding;
                this.attribute = webMethod.attribute; 
                this.declaration = webMethod.declaration;
            }
            ParameterInfo[] beginParamInfos = beginMethodInfo.GetParameters();
            if (beginParamInfos.Length < 2 || 
                beginParamInfos[beginParamInfos.Length - 1].ParameterType != typeof(object) ||
                beginParamInfos[beginParamInfos.Length - 2].ParameterType != typeof(AsyncCallback)) { 
                throw new InvalidOperationException(Res.GetString(Res.WebMethodMissingParams, beginMethodInfo.DeclaringType.FullName, beginMethodInfo.Name, 
                    typeof(AsyncCallback).FullName, typeof(object).FullName));
            } 

            stateParam = beginParamInfos[beginParamInfos.Length - 1];
            callbackParam = beginParamInfos[beginParamInfos.Length - 2];
 
            inParams = GetInParameters(beginMethodInfo, beginParamInfos, 0, beginParamInfos.Length - 2, true);
 
            ParameterInfo[] endParamInfos = endMethodInfo.GetParameters(); 
            resultParam = endParamInfos[0];
            outParams = GetOutParameters(endMethodInfo, endParamInfos, 1, endParamInfos.Length - 1, true); 

            parameters = new ParameterInfo[inParams.Length + outParams.Length];
            inParams.CopyTo(parameters, 0);
            outParams.CopyTo(parameters, inParams.Length); 

            retType = endMethodInfo.ReturnType; 
            isVoid = retType == typeof(void); 
            attributes = new Hashtable();
        } 

        /// 
        /// 
        ///    [To be supplied.] 
        /// 
        public override string ToString() { 
            return methodInfo.ToString(); 
        }
 
        // This takes in parameters, and returns return value followed by out parameters in an array
        /// 
        /// 
        ///    [To be supplied.] 
        /// 
        [PermissionSet(SecurityAction.LinkDemand, Name="FullTrust")] 
        public object[] Invoke(object target, object[] values) { 
            if (outParams.Length > 0) {
                object[] newValues = new object[parameters.Length]; 
                for (int i = 0; i < inParams.Length; i++) {
                    newValues[inParams[i].Position] = values[i];
                }
                values = newValues; 
            }
            object returnValue = methodInfo.Invoke(target, values); 
            if (outParams.Length > 0) { 
                int count = outParams.Length;
                if (!isVoid) count++; 
                object[] results = new object[count];
                count = 0;
                if (!isVoid) results[count++] = returnValue;
                for (int i = 0; i < outParams.Length; i++) { 
                    results[count++] = values[outParams[i].Position];
                } 
                return results; 
            }
            else if (isVoid) { 
                return emptyObjectArray;
            }
            else {
                return new object[] { returnValue }; 
            }
        } 
 
        /// 
        ///  
        ///    [To be supplied.]
        /// 
        [PermissionSet(SecurityAction.LinkDemand, Name="FullTrust")]
        public IAsyncResult BeginInvoke(object target, object[] values, AsyncCallback callback, object asyncState) { 
            object[] asyncValues = new object[values.Length + 2];
            values.CopyTo(asyncValues, 0); 
            asyncValues[values.Length] = callback; 
            asyncValues[values.Length + 1] = asyncState;
            return (IAsyncResult)methodInfo.Invoke(target, asyncValues); 
        }

        /// 
        ///  
        ///    [To be supplied.]
        ///  
        [PermissionSet(SecurityAction.LinkDemand, Name="FullTrust")] 
        public object[] EndInvoke(object target, IAsyncResult asyncResult) {
            object[] values = new object[outParams.Length + 1]; 
            values[0] = asyncResult;
            object returnValue = endMethodInfo.Invoke(target, values);
            if (!isVoid) {
                values[0] = returnValue; 
                return values;
            } 
            else if (outParams.Length > 0) { 
                object[] newValues = new object[outParams.Length];
                Array.Copy(values, 1, newValues, 0, newValues.Length); 
                return newValues;
            }
            else {
                return emptyObjectArray; 
            }
        } 
 
        internal WebServiceBindingAttribute Binding {
            get { return binding; } 
        }

        internal MethodInfo Declaration {
            get { return declaration; } 
        }
 
        ///  
        /// 
        ///    [To be supplied.] 
        /// 
        public Type DeclaringType {
            get { return methodInfo.DeclaringType; }
        } 

        ///  
        ///  
        ///    [To be supplied.]
        ///  
        public string Name {
            get { return methodName; }
        }
 
        /// 
        ///  
        ///    [To be supplied.] 
        /// 
        public ParameterInfo AsyncResultParameter { 
            get { return resultParam; }
        }

        ///  
        /// 
        ///    [To be supplied.] 
        ///  
        public ParameterInfo AsyncCallbackParameter {
            get { return callbackParam; } 
        }

        /// 
        ///  
        ///    [To be supplied.]
        ///  
        public ParameterInfo AsyncStateParameter { 
            get { return stateParam; }
        } 

        /// 
        /// 
        ///    [To be supplied.] 
        /// 
        public Type ReturnType { 
            get { return retType; } 
        }
 
        /// 
        /// 
        ///    [To be supplied.]
        ///  
        public bool IsVoid {
            get { return isVoid; } 
        } 

        ///  
        /// 
        ///    [To be supplied.]
        /// 
        public bool IsAsync { 
            get { return endMethodInfo != null; }
        } 
 
        /// 
        ///  
        ///    [To be supplied.]
        /// 
        public ParameterInfo[] InParameters {
            get { return inParams; } 
        }
 
        ///  
        /// 
        ///    [To be supplied.] 
        /// 
        public ParameterInfo[] OutParameters {
            get { return outParams; }
        } 

        ///  
        ///  
        ///    [To be supplied.]
        ///  
        public ParameterInfo[] Parameters {
            get { return parameters; }
        }
 
        /// 
        ///  
        ///    [To be supplied.] 
        /// 
        public object[] GetCustomAttributes(Type type) { 
            object[] attrForType = null;
            attrForType = (object[])attributes[type];
            if (attrForType != null)
                return attrForType; 
            lock (attributes) {
                attrForType = (object[])attributes[type]; 
                if (attrForType == null){ 
                    if (declaration != null) {
                        object[] declAttributes = declaration.GetCustomAttributes(type, false); 
                        object[] implAttributes = methodInfo.GetCustomAttributes(type, false);
                        if (implAttributes.Length > 0) {
                            if (CanMerge(type)) {
                                ArrayList all = new ArrayList(); 
                                for (int i = 0; i < declAttributes.Length; i++) {
                                    all.Add(declAttributes[i]); 
                                } 
                                for (int i = 0; i < implAttributes.Length; i++) {
                                    all.Add(implAttributes[i]); 
                                }
                                attrForType = (object[])all.ToArray(type);
                            }
                            else { 
                                throw new InvalidOperationException(Res.GetString(Res.ContractOverride, methodInfo.Name, methodInfo.DeclaringType.FullName, declaration.DeclaringType.FullName, declaration.ToString(), implAttributes[0].ToString()));
                            } 
                        } 
                        else {
                            attrForType = declAttributes; 
                        }
                    }
                    else {
                        attrForType = methodInfo.GetCustomAttributes(type, false); 
                    }
                    attributes[type] = attrForType; 
                } 
            }
            return attrForType; 
        }


        ///  
        /// 
        ///    [To be supplied.] 
        ///  
        public object GetCustomAttribute(Type type) {
            object[] attrs = GetCustomAttributes(type); 
            if (attrs.Length == 0) return null;
            return attrs[0];
        }
 
        internal WebMethodAttribute MethodAttribute {
            get { 
                if (attribute == null) { 
                    attribute = (WebMethodAttribute)GetCustomAttribute(typeof(WebMethodAttribute));
                    if (attribute == null) { 
                        attribute = new WebMethodAttribute();
                    }
                }
                return attribute; 
            }
        } 
 
        /// 
        ///  
        ///    [To be supplied.]
        /// 
        public ICustomAttributeProvider CustomAttributeProvider {
            // Custom attributes are always on the XXX ([....]) or BeginXXX (async) method. 
            get { return methodInfo; }
        } 
 
        /// 
        ///  
        ///    [To be supplied.]
        /// 
        public ICustomAttributeProvider ReturnTypeCustomAttributeProvider {
            get { 
                if (declaration != null)
                    return declaration.ReturnTypeCustomAttributes; 
                return methodInfo.ReturnTypeCustomAttributes; 
            }
        } 

        // Do not use this to property get custom attributes.  Instead use the CustomAttributeProvider
        // property which automatically handles where the custom attributes belong for async methods
        // (which are actually two methods: BeginXXX and EndXXX). 
        /// 
        ///  
        ///    [To be supplied.] 
        /// 
        public MethodInfo MethodInfo { 
            get { return endMethodInfo == null ? methodInfo : null; }
        }

        ///  
        /// 
        ///    [To be supplied.] 
        ///  
        public MethodInfo BeginMethodInfo {
            get { return methodInfo; } 
        }

        /// 
        ///  
        ///    [To be supplied.]
        ///  
        public MethodInfo EndMethodInfo { 
            get { return endMethodInfo; }
        } 

        static ParameterInfo[] GetInParameters(MethodInfo methodInfo, ParameterInfo[] paramInfos, int start, int length, bool mustBeIn) {
            int count = 0;
            for (int i = 0; i < length; i++) { 
                ParameterInfo paramInfo = paramInfos[i + start];
                if (IsInParameter(paramInfo)) { 
                    count++; 
                }
                else if (mustBeIn) { 
                    throw new InvalidOperationException(Res.GetString(Res.WebBadOutParameter, paramInfo.Name, methodInfo.DeclaringType.FullName,  paramInfo.Name));
                }
            }
 
            ParameterInfo[] ins = new ParameterInfo[count];
            count = 0; 
            for (int i = 0; i < length; i++) { 
                ParameterInfo paramInfo = paramInfos[i + start];
                if (IsInParameter(paramInfo)) { 
                    ins[count++] = paramInfo;
                }
            }
            return ins; 
        }
 
        static ParameterInfo[] GetOutParameters(MethodInfo methodInfo, ParameterInfo[] paramInfos, int start, int length, bool mustBeOut) { 
            int count = 0;
            for (int i = 0; i < length; i++) { 
                ParameterInfo paramInfo = paramInfos[i + start];
                if (IsOutParameter(paramInfo)) {
                    count++;
                } 
                else if (mustBeOut) {
                    throw new InvalidOperationException(Res.GetString(Res.WebInOutParameter, paramInfo.Name, methodInfo.DeclaringType.FullName,  paramInfo.Name)); 
                } 
            }
 
            ParameterInfo[] outs = new ParameterInfo[count];
            count = 0;
            for (int i = 0; i < length; i++) {
                ParameterInfo paramInfo = paramInfos[i + start]; 
                if (IsOutParameter(paramInfo)) {
                    outs[count++] = paramInfo; 
                } 
            }
            return outs; 
        }

        static bool IsInParameter(ParameterInfo paramInfo) {
            return !paramInfo.IsOut; 
        }
 
        static bool IsOutParameter(ParameterInfo paramInfo) { 
            return paramInfo.IsOut || paramInfo.ParameterType.IsByRef;
        } 

        /// 
        /// 
        ///    [To be supplied.] 
        /// 
        public static bool IsBeginMethod(MethodInfo methodInfo) { 
            return typeof(IAsyncResult).IsAssignableFrom(methodInfo.ReturnType) && 
                methodInfo.Name.StartsWith("Begin", StringComparison.Ordinal);
        } 

        /// 
        /// 
        ///    [To be supplied.] 
        /// 
        public static bool IsEndMethod(MethodInfo methodInfo) { 
            ParameterInfo[] paramInfos = methodInfo.GetParameters(); 
            return paramInfos.Length > 0 &&
                typeof(IAsyncResult).IsAssignableFrom(paramInfos[0].ParameterType) && 
                methodInfo.Name.StartsWith("End", StringComparison.Ordinal);
        }

        ///  
        /// 
        ///    [To be supplied.] 
        ///  
        public static LogicalMethodInfo[] Create(MethodInfo[] methodInfos) {
            return Create(methodInfos, LogicalMethodTypes.Async | LogicalMethodTypes.[....], null); 
        }


        ///  
        /// 
        ///    [To be supplied.] 
        ///  
        public static LogicalMethodInfo[] Create(MethodInfo[] methodInfos, LogicalMethodTypes types) {
            return Create(methodInfos, types, null); 
        }

        internal static LogicalMethodInfo[] Create(MethodInfo[] methodInfos, LogicalMethodTypes types, Hashtable declarations) {
            ArrayList begins = (types & LogicalMethodTypes.Async) != 0 ? new ArrayList() : null; 
            Hashtable ends = (types & LogicalMethodTypes.Async) != 0 ? new Hashtable() : null;
            ArrayList syncs = (types & LogicalMethodTypes.[....]) != 0 ? new ArrayList() : null; 
 
            for (int i = 0; i < methodInfos.Length; i++) {
                MethodInfo methodInfo = methodInfos[i]; 
                if (IsBeginMethod(methodInfo)) {
                    if (begins != null) begins.Add(methodInfo);
                }
                else if (IsEndMethod(methodInfo)) { 
                    if (ends != null) ends.Add(methodInfo.Name, methodInfo);
                } 
                else { 
                    if (syncs != null) syncs.Add(methodInfo);
                } 
            }

            int beginsCount = begins == null ? 0 : begins.Count;
            int syncsCount = syncs == null ? 0 : syncs.Count; 
            int count = syncsCount + beginsCount;
            LogicalMethodInfo[] methods = new LogicalMethodInfo[count]; 
            count = 0; 
            for (int i = 0; i < syncsCount; i++) {
                MethodInfo syncMethod = (MethodInfo)syncs[i]; 
                WebMethod webMethod = declarations == null ? null : (WebMethod)declarations[syncMethod];
                methods[count] = new LogicalMethodInfo(syncMethod, webMethod);
                methods[count].CheckContractOverride();
                count++; 
            }
            for (int i = 0; i < beginsCount; i++) { 
                MethodInfo beginMethodInfo = (MethodInfo)begins[i]; 
                string endName = "End" + beginMethodInfo.Name.Substring(5);
                MethodInfo endMethodInfo = (MethodInfo)ends[endName]; 
                if (endMethodInfo == null) {
                    throw new InvalidOperationException(Res.GetString(Res.WebAsyncMissingEnd, beginMethodInfo.DeclaringType.FullName, beginMethodInfo.Name, endName));
                }
                WebMethod webMethod = declarations == null ? null : (WebMethod)declarations[beginMethodInfo]; 
                methods[count++] = new LogicalMethodInfo(beginMethodInfo, endMethodInfo, webMethod);
            } 
 
            return methods;
        } 

        internal static HashAlgorithm HashAlgorithm {
            get {
                if (hash == null) { 
                    hash = SHA1.Create();
                } 
                return hash; 
            }
        } 

        internal string GetKey() {
            if (methodInfo == null)
                return string.Empty; 
            string key = methodInfo.DeclaringType.FullName + ":" + methodInfo.ToString();
            // for very long method signatures use a hash string instead of actual method signature. 
            if (key.Length > 1024) { 
                byte[] bytes = HashAlgorithm.ComputeHash(Encoding.UTF8.GetBytes(key));
                key = Convert.ToBase64String(bytes); 
            }
            return key;
        }
 
        internal void CheckContractOverride() {
            if (declaration == null) 
                return; 
            methodInfo.GetParameters();
            ParameterInfo[] parameters = methodInfo.GetParameters(); 
            foreach (ParameterInfo p in parameters) {
                object[] attrs = p.GetCustomAttributes(false);
                foreach (object o in attrs) {
                    if (o.GetType().Namespace == "System.Xml.Serialization") { 
                        throw new InvalidOperationException(Res.GetString(Res.ContractOverride, methodInfo.Name, methodInfo.DeclaringType.FullName, declaration.DeclaringType.FullName, declaration.ToString(), o.ToString()));
                    } 
                } 
            }
        } 

        internal static bool CanMerge(Type type) {
            if (type == typeof(SoapHeaderAttribute))
                return true; 
            if (typeof(SoapExtensionAttribute).IsAssignableFrom(type))
                return true; 
            return false; 
        }
    } 
}

// 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