SignatureHelper.cs source code in C# .NET

Source code for the .NET framework in C#

                        

Code:

/ 4.0 / 4.0 / untmp / DEVDIV_TFS / Dev10 / Releases / RTMRel / ndp / clr / src / BCL / System / Reflection / Emit / SignatureHelper.cs / 1305376 / SignatureHelper.cs

                            // ==++== 
//
//   Copyright (c) Microsoft Corporation.  All rights reserved.
//
// ==--== 
// [....]
// 
 
namespace System.Reflection.Emit
{ 
    using System.Text;
    using System;
    using System.Diagnostics.Contracts;
    using System.Reflection; 
    using System.Runtime.CompilerServices;
    using System.Runtime.InteropServices; 
    using System.Runtime.Versioning; 
    using System.Security.Permissions;
 
    [ClassInterface(ClassInterfaceType.None)]
    [ComDefaultInterface(typeof(_SignatureHelper))]
[System.Runtime.InteropServices.ComVisible(true)]
    public sealed class SignatureHelper : _SignatureHelper 
    {
        #region Consts Fields 
        private const int NO_SIZE_IN_SIG = -1; 
        #endregion
 
        #region Static Members
        [System.Security.SecuritySafeCritical]  // auto-generated
        public static SignatureHelper GetMethodSigHelper(Module mod, Type returnType, Type[] parameterTypes)
        { 
            return GetMethodSigHelper(mod, CallingConventions.Standard, returnType, null, null, parameterTypes, null, null);
        } 
 
        [System.Security.SecurityCritical]  // auto-generated
        internal static SignatureHelper GetMethodSigHelper(Module mod, CallingConventions callingConvention, Type returnType, int cGenericParam) 
        {
            return GetMethodSigHelper(mod, callingConvention, cGenericParam, returnType, null, null, null, null, null);
        }
 
        [System.Security.SecuritySafeCritical]  // auto-generated
        public static SignatureHelper GetMethodSigHelper(Module mod, CallingConventions callingConvention, Type returnType) 
        { 
            return GetMethodSigHelper(mod, callingConvention, returnType, null, null, null, null, null);
        } 

        internal static SignatureHelper GetMethodSpecSigHelper(Module scope, Type[] inst)
        {
            SignatureHelper sigHelp = new SignatureHelper(scope, MdSigCallingConvention.GenericInst); 
            sigHelp.AddData(inst.Length);
            foreach(Type t in inst) 
                sigHelp.AddArgument(t); 
            return sigHelp;
        } 

        [System.Security.SecurityCritical]  // auto-generated
        internal static SignatureHelper GetMethodSigHelper(
            Module scope, CallingConventions callingConvention, 
            Type returnType, Type[] requiredReturnTypeCustomModifiers, Type[] optionalReturnTypeCustomModifiers,
            Type[] parameterTypes, Type[][] requiredParameterTypeCustomModifiers, Type[][] optionalParameterTypeCustomModifiers) 
        { 
            return GetMethodSigHelper(scope, callingConvention, 0, returnType, requiredReturnTypeCustomModifiers,
                optionalReturnTypeCustomModifiers, parameterTypes, requiredParameterTypeCustomModifiers, optionalParameterTypeCustomModifiers); 
        }

        [System.Security.SecurityCritical]  // auto-generated
        internal static SignatureHelper GetMethodSigHelper( 
            Module scope, CallingConventions callingConvention, int cGenericParam,
            Type returnType, Type[] requiredReturnTypeCustomModifiers, Type[] optionalReturnTypeCustomModifiers, 
            Type[] parameterTypes, Type[][] requiredParameterTypeCustomModifiers, Type[][] optionalParameterTypeCustomModifiers) 
        {
            SignatureHelper sigHelp; 
            MdSigCallingConvention intCall;

            if (returnType == null)
            { 
                returnType = typeof(void);
            } 
 
            intCall = MdSigCallingConvention.Default;
 
            if ((callingConvention & CallingConventions.VarArgs) == CallingConventions.VarArgs)
                intCall = MdSigCallingConvention.Vararg;

            if (cGenericParam > 0) 
            {
                intCall |= MdSigCallingConvention.Generic; 
            } 

            if ((callingConvention & CallingConventions.HasThis) == CallingConventions.HasThis) 
                intCall |= MdSigCallingConvention.HasThis;

            sigHelp = new SignatureHelper(scope, intCall, cGenericParam, returnType,
                                            requiredReturnTypeCustomModifiers, optionalReturnTypeCustomModifiers); 
            sigHelp.AddArguments(parameterTypes, requiredParameterTypeCustomModifiers, optionalParameterTypeCustomModifiers);
 
            return sigHelp; 
        }
 
        [System.Security.SecuritySafeCritical]  // auto-generated
        public static SignatureHelper GetMethodSigHelper(Module mod, CallingConvention unmanagedCallConv, Type returnType)
        {
            SignatureHelper sigHelp; 
            MdSigCallingConvention intCall;
 
            if (returnType == null) 
                returnType = typeof(void);
 
            if (unmanagedCallConv == CallingConvention.Cdecl)
            {
                intCall = MdSigCallingConvention.C;
            } 
            else if (unmanagedCallConv == CallingConvention.StdCall || unmanagedCallConv == CallingConvention.Winapi)
            { 
                intCall = MdSigCallingConvention.StdCall; 
            }
            else if (unmanagedCallConv == CallingConvention.ThisCall) 
            {
                intCall = MdSigCallingConvention.ThisCall;
            }
            else if (unmanagedCallConv == CallingConvention.FastCall) 
            {
                intCall = MdSigCallingConvention.FastCall; 
            } 
            else
            { 
                throw new ArgumentException(Environment.GetResourceString("Argument_UnknownUnmanagedCallConv"), "unmanagedCallConv");
            }

            sigHelp = new SignatureHelper(mod, intCall, returnType, null, null); 

            return sigHelp; 
        } 

        public static SignatureHelper GetLocalVarSigHelper() 
        {
            return GetLocalVarSigHelper(null);
        }
 
        public static SignatureHelper GetMethodSigHelper(CallingConventions callingConvention, Type returnType)
        { 
            return GetMethodSigHelper(null, callingConvention, returnType); 
        }
 
        public static SignatureHelper GetMethodSigHelper(CallingConvention unmanagedCallingConvention, Type returnType)
        {
            return GetMethodSigHelper(null, unmanagedCallingConvention, returnType);
        } 

        public static SignatureHelper GetLocalVarSigHelper(Module mod) 
        { 
            return new SignatureHelper(mod, MdSigCallingConvention.LocalSig);
        } 

        public static SignatureHelper GetFieldSigHelper(Module mod)
        {
            return new SignatureHelper(mod, MdSigCallingConvention.Field); 
        }
 
        public static SignatureHelper GetPropertySigHelper(Module mod, Type returnType, Type[] parameterTypes) 
        {
            return GetPropertySigHelper(mod, returnType, null, null, parameterTypes, null, null); 
        }

        [System.Security.SecuritySafeCritical]  // auto-generated
        public static SignatureHelper GetPropertySigHelper(Module mod, 
            Type returnType, Type[] requiredReturnTypeCustomModifiers, Type[] optionalReturnTypeCustomModifiers,
            Type[] parameterTypes, Type[][] requiredParameterTypeCustomModifiers, Type[][] optionalParameterTypeCustomModifiers) 
        { 
            return GetPropertySigHelper(mod, (CallingConventions)0, returnType, requiredReturnTypeCustomModifiers, optionalReturnTypeCustomModifiers,
                parameterTypes, requiredParameterTypeCustomModifiers, optionalParameterTypeCustomModifiers); 
        }
        [System.Security.SecuritySafeCritical]  // auto-generated
        public static SignatureHelper GetPropertySigHelper(Module mod, CallingConventions callingConvention,
            Type returnType, Type[] requiredReturnTypeCustomModifiers, Type[] optionalReturnTypeCustomModifiers, 
            Type[] parameterTypes, Type[][] requiredParameterTypeCustomModifiers, Type[][] optionalParameterTypeCustomModifiers)
        { 
            SignatureHelper sigHelp; 

            if (returnType == null) 
            {
                returnType = typeof(void);
            }
 
            MdSigCallingConvention intCall = MdSigCallingConvention.Property;
 
            if ((callingConvention & CallingConventions.HasThis) == CallingConventions.HasThis) 
                intCall |= MdSigCallingConvention.HasThis;
 
            sigHelp = new SignatureHelper(mod, intCall,
                returnType, requiredReturnTypeCustomModifiers, optionalReturnTypeCustomModifiers);
            sigHelp.AddArguments(parameterTypes, requiredParameterTypeCustomModifiers, optionalParameterTypeCustomModifiers);
 
            return sigHelp;
        } 
 
        [System.Security.SecurityCritical]  // auto-generated
        internal static SignatureHelper GetTypeSigToken(Module mod, Type type) 
        {
            if (mod == null)
                throw new ArgumentNullException("module");
 
            if (type == null)
                throw new ArgumentNullException("type"); 
 
            return new SignatureHelper(mod, type);
        } 
        #endregion

        #region Private Data Members
        private byte[] m_signature; 
        private int m_currSig; // index into m_signature buffer for next available byte
        private int m_sizeLoc; // index into m_signature buffer to put m_argCount (will be NO_SIZE_IN_SIG if no arg count is needed) 
        private ModuleBuilder m_module; 
        private bool m_sigDone;
        private int m_argCount; // tracking number of arguments in the signature 
        #endregion

        #region Constructor
        private SignatureHelper(Module mod, MdSigCallingConvention callingConvention) 
        {
            // Use this constructor to instantiate a local var sig  or Field where return type is not applied. 
            Init(mod, callingConvention); 
        }
 
        [System.Security.SecurityCritical]  // auto-generated
        private SignatureHelper(Module mod, MdSigCallingConvention callingConvention, int cGenericParameters,
            Type returnType, Type[] requiredCustomModifiers, Type[] optionalCustomModifiers)
        { 
            // Use this constructor to instantiate a any signatures that will require a return type.
            Init(mod, callingConvention, cGenericParameters); 
 
            if (callingConvention == MdSigCallingConvention.Field)
                throw new ArgumentException(Environment.GetResourceString("Argument_BadFieldSig")); 

            AddOneArgTypeHelper(returnType, requiredCustomModifiers, optionalCustomModifiers);
        }
 
        [System.Security.SecurityCritical]  // auto-generated
        private SignatureHelper(Module mod, MdSigCallingConvention callingConvention, 
            Type returnType, Type[] requiredCustomModifiers, Type[] optionalCustomModifiers) 
            : this(mod, callingConvention, 0, returnType, requiredCustomModifiers, optionalCustomModifiers)
        { 
        }

        [System.Security.SecurityCritical]  // auto-generated
        private SignatureHelper(Module mod, Type type) 
        {
            Init(mod); 
 
            AddOneArgTypeHelper(type);
        } 

        private void Init(Module mod)
        {
            m_signature = new byte[32]; 
            m_currSig = 0;
            m_module = mod as ModuleBuilder; 
            m_argCount = 0; 
            m_sigDone = false;
            m_sizeLoc = NO_SIZE_IN_SIG; 

            if (m_module == null && mod != null)
                throw new ArgumentException(Environment.GetResourceString("NotSupported_MustBeModuleBuilder"));
        } 

        private void Init(Module mod, MdSigCallingConvention callingConvention) 
        { 
            Init(mod, callingConvention, 0);
        } 

        private void Init(Module mod, MdSigCallingConvention callingConvention, int cGenericParam)
        {
            Init(mod); 

            AddData((byte)callingConvention); 
 
            if (callingConvention == MdSigCallingConvention.Field ||
                callingConvention == MdSigCallingConvention.GenericInst) 
            {
                m_sizeLoc = NO_SIZE_IN_SIG;
            }
            else 
            {
                if (cGenericParam > 0) 
                    AddData(cGenericParam); 

                m_sizeLoc = m_currSig++; 
            }
        }

        #endregion 

        #region Private Members 
        [System.Security.SecurityCritical]  // auto-generated 
        private void AddOneArgTypeHelper(Type argument, bool pinned)
        { 
            if (pinned)
                AddElementType(CorElementType.Pinned);

            AddOneArgTypeHelper(argument); 
        }
 
        [System.Security.SecurityCritical]  // auto-generated 
        private void AddOneArgTypeHelper(Type clsArgument, Type[] requiredCustomModifiers, Type[] optionalCustomModifiers)
        { 
            // This function will not increase the argument count. It only fills in bytes
            // in the signature based on clsArgument. This helper is called for return type.

            Contract.Requires(clsArgument != null); 
            Contract.Requires((optionalCustomModifiers == null && requiredCustomModifiers == null) || !clsArgument.ContainsGenericParameters);
 
            if (optionalCustomModifiers != null) 
            {
                for (int i = 0; i < optionalCustomModifiers.Length; i++) 
                {
                    Type t = optionalCustomModifiers[i];

                    if (t == null) 
                        throw new ArgumentNullException("optionalCustomModifiers");
 
                    if (t.HasElementType) 
                        throw new ArgumentException(Environment.GetResourceString("Argument_ArraysInvalid"), "optionalCustomModifiers");
 
                    if (t.ContainsGenericParameters)
                        throw new ArgumentException(Environment.GetResourceString("Argument_GenericsInvalid"), "optionalCustomModifiers");

                    AddElementType(CorElementType.CModOpt); 

                    int token = m_module.GetTypeToken(t).Token; 
                    Contract.Assert(!MetadataToken.IsNullToken(token)); 
                    AddToken(token);
                } 
            }

            if (requiredCustomModifiers != null)
            { 
                for (int i = 0; i < requiredCustomModifiers.Length; i++)
                { 
                    Type t = requiredCustomModifiers[i]; 

                    if (t == null) 
                        throw new ArgumentNullException("requiredCustomModifiers");

                    if (t.HasElementType)
                        throw new ArgumentException(Environment.GetResourceString("Argument_ArraysInvalid"), "requiredCustomModifiers"); 

                    if (t.ContainsGenericParameters) 
                        throw new ArgumentException(Environment.GetResourceString("Argument_GenericsInvalid"), "requiredCustomModifiers"); 

                    AddElementType(CorElementType.CModReqd); 

                    int token = m_module.GetTypeToken(t).Token;
                    Contract.Assert(!MetadataToken.IsNullToken(token));
                    AddToken(token); 
                }
            } 
 
            AddOneArgTypeHelper(clsArgument);
        } 

        [System.Security.SecurityCritical]  // auto-generated
        private void AddOneArgTypeHelper(Type clsArgument) { AddOneArgTypeHelperWorker(clsArgument, false); }
        [System.Security.SecurityCritical]  // auto-generated 
        private void AddOneArgTypeHelperWorker(Type clsArgument, bool lastWasGenericInst)
        { 
            if (clsArgument.IsGenericParameter) 
            {
                if (clsArgument.DeclaringMethod != null) 
                    AddElementType(CorElementType.MVar);
                else
                    AddElementType(CorElementType.Var);
 
                AddData(clsArgument.GenericParameterPosition);
            } 
            else if (clsArgument.IsGenericType && (!clsArgument.IsGenericTypeDefinition || !lastWasGenericInst)) 
            {
                AddElementType(CorElementType.GenericInst); 

                AddOneArgTypeHelperWorker(clsArgument.GetGenericTypeDefinition(), true);

                Type[] args = clsArgument.GetGenericArguments(); 

                AddData(args.Length); 
 
                foreach (Type t in args)
                    AddOneArgTypeHelper(t); 
            }
            else if (clsArgument is TypeBuilder)
            {
                TypeBuilder clsBuilder = (TypeBuilder)clsArgument; 
                TypeToken tkType;
 
                if (clsBuilder.Module.Equals(m_module)) 
                {
                    tkType = clsBuilder.TypeToken; 
                }
                else
                {
                    tkType = m_module.GetTypeToken(clsArgument); 
                }
 
                if (clsArgument.IsValueType) 
                {
                    InternalAddTypeToken(tkType, CorElementType.ValueType); 
                }
                else
                {
                    InternalAddTypeToken(tkType, CorElementType.Class); 
                }
            } 
            else if (clsArgument is EnumBuilder) 
            {
                TypeBuilder clsBuilder = ((EnumBuilder)clsArgument).m_typeBuilder; 
                TypeToken tkType;

                if (clsBuilder.Module.Equals(m_module))
                { 
                    tkType = clsBuilder.TypeToken;
                } 
                else 
                {
                    tkType = m_module.GetTypeToken(clsArgument); 
                }

                if (clsArgument.IsValueType)
                { 
                    InternalAddTypeToken(tkType, CorElementType.ValueType);
                } 
                else 
                {
                    InternalAddTypeToken(tkType, CorElementType.Class); 
                }
            }
            else if (clsArgument.IsByRef)
            { 
                AddElementType(CorElementType.ByRef);
                clsArgument = clsArgument.GetElementType(); 
                AddOneArgTypeHelper(clsArgument); 
            }
            else if (clsArgument.IsPointer) 
            {
                AddElementType(CorElementType.Ptr);
                AddOneArgTypeHelper(clsArgument.GetElementType());
            } 
            else if (clsArgument.IsArray)
            { 
                if (clsArgument.IsSzArray) 
                {
                    AddElementType(CorElementType.SzArray); 

                    AddOneArgTypeHelper(clsArgument.GetElementType());
                }
                else 
                {
                    AddElementType(CorElementType.Array); 
 
                    AddOneArgTypeHelper(clsArgument.GetElementType());
 
                    // put the rank information
                    int rank = clsArgument.GetArrayRank();
                    AddData(rank);     // rank
                    AddData(0);     // upper bounds 
                    AddData(rank);  // lower bound
                    for (int i = 0; i < rank; i++) 
                        AddData(0); 
                }
            } 
            else
            {
                CorElementType type = CorElementType.Max;
 
                if (clsArgument.IsRuntimeType)
                { 
                    type = RuntimeTypeHandle.GetCorElementType((RuntimeType)clsArgument); 

                    //GetCorElementType returns CorElementType.Class for both object and string 
                    if (type == CorElementType.Class)
                    {
                        if (clsArgument == typeof(object))
                            type = CorElementType.Object; 
                        else if (clsArgument == typeof(string))
                            type = CorElementType.String; 
                    } 
                }
 
                if (IsSimpleType(type))
                {
                    AddElementType(type);
                } 
                else if (m_module == null)
                { 
                    InternalAddRuntimeType(clsArgument); 
                }
                else if (clsArgument.IsValueType) 
                {
                    InternalAddTypeToken(m_module.GetTypeToken(clsArgument), CorElementType.ValueType);
                }
                else 
                {
                    InternalAddTypeToken(m_module.GetTypeToken(clsArgument), CorElementType.Class); 
                } 
            }
        } 

        private void AddData(int data)
        {
            // A managed representation of CorSigCompressData; 

            if (m_currSig + 4 > m_signature.Length) 
            { 
                m_signature = ExpandArray(m_signature);
            } 

            if (data <= 0x7F)
            {
                m_signature[m_currSig++] = (byte)(data & 0xFF); 
            }
            else if (data <= 0x3FFF) 
            { 
                m_signature[m_currSig++] = (byte)((data >>8) | 0x80);
                m_signature[m_currSig++] = (byte)(data & 0xFF); 
            }
            else if (data <= 0x1FFFFFFF)
            {
                m_signature[m_currSig++] = (byte)((data >>24) | 0xC0); 
                m_signature[m_currSig++] = (byte)((data >>16) & 0xFF);
                m_signature[m_currSig++] = (byte)((data >>8) & 0xFF); 
                m_signature[m_currSig++] = (byte)((data) & 0xFF); 
            }
            else 
            {
                throw new ArgumentException(Environment.GetResourceString("Argument_LargeInteger"));
            }
 
        }
 
        private void AddData(uint data) 
        {
            if (m_currSig + 4 > m_signature.Length) 
            {
                m_signature = ExpandArray(m_signature);
            }
 
            m_signature[m_currSig++] = (byte)((data)     & 0xFF);
            m_signature[m_currSig++] = (byte)((data>>8)  & 0xFF); 
            m_signature[m_currSig++] = (byte)((data>>16) & 0xFF); 
            m_signature[m_currSig++] = (byte)((data>>24) & 0xFF);
        } 

        private void AddData(ulong data)
        {
            if (m_currSig + 8 > m_signature.Length) 
            {
                m_signature = ExpandArray(m_signature); 
            } 

            m_signature[m_currSig++] = (byte)((data)     & 0xFF); 
            m_signature[m_currSig++] = (byte)((data>>8)  & 0xFF);
            m_signature[m_currSig++] = (byte)((data>>16) & 0xFF);
            m_signature[m_currSig++] = (byte)((data>>24) & 0xFF);
            m_signature[m_currSig++] = (byte)((data>>32) & 0xFF); 
            m_signature[m_currSig++] = (byte)((data>>40) & 0xFF);
            m_signature[m_currSig++] = (byte)((data>>48) & 0xFF); 
            m_signature[m_currSig++] = (byte)((data>>56) & 0xFF); 
        }
 
        private void AddElementType(CorElementType cvt)
        {
            // Adds an element to the signature.  A managed represenation of CorSigCompressElement
            if (m_currSig + 1 > m_signature.Length) 
                m_signature = ExpandArray(m_signature);
 
            m_signature[m_currSig++] = (byte)cvt; 
        }
 
        private void AddToken(int token)
        {
            // A managed represenation of CompressToken
            // Pulls the token appart to get a rid, adds some appropriate bits 
            // to the token and then adds this to the signature.
 
            int rid =  (token & 0x00FFFFFF); //This is RidFromToken; 
            MetadataTokenType type = (MetadataTokenType)(token & unchecked((int)0xFF000000)); //This is TypeFromToken;
 
            if (rid > 0x3FFFFFF)
            {
                // token is too big to be compressed
                throw new ArgumentException(Environment.GetResourceString("Argument_LargeInteger")); 
            }
 
            rid = (rid << 2); 

            // TypeDef is encoded with low bits 00 
            // TypeRef is encoded with low bits 01
            // TypeSpec is encoded with low bits 10
            if (type == MetadataTokenType.TypeRef)
            { 
                //if type is mdtTypeRef
                rid|=0x1; 
            } 
            else if (type == MetadataTokenType.TypeSpec)
            { 
                //if type is mdtTypeSpec
                rid|=0x2;
            }
 
            AddData(rid);
        } 
 
        private void InternalAddTypeToken(TypeToken clsToken, CorElementType CorType)
        { 
            // Add a type token into signature. CorType will be either CorElementType.Class or CorElementType.ValueType
            AddElementType(CorType);
            AddToken(clsToken.Token);
        } 

        [System.Security.SecurityCritical]  // auto-generated 
        private unsafe void InternalAddRuntimeType(Type type) 
        {
            // Add a runtime type into the signature. 

            AddElementType(CorElementType.Internal);

            void* handle = (void*)type.GetTypeHandleInternal().Value; 

            // Internal types must have their pointer written into the signature directly (we don't 
            // want to convert to little-endian format on big-endian machines because the value is 
            // going to be extracted and used directly as a pointer (and only within this process)).
 
            if (m_currSig + sizeof(void*) > m_signature.Length)
                m_signature = ExpandArray(m_signature);

            byte *phandle = (byte*)&handle; 
            for (int i = 0; i < sizeof(void*); i++)
                m_signature[m_currSig++] = phandle[i]; 
        } 

        private byte[] ExpandArray(byte[] inArray) 
        {
            // Expand the signature buffer size
            return ExpandArray(inArray, inArray.Length * 2);
        } 

        private byte[] ExpandArray(byte[] inArray, int requiredLength) 
        { 
            // Expand the signature buffer size
 
            if (requiredLength < inArray.Length)
                requiredLength = inArray.Length*2;

            byte[] outArray = new byte[requiredLength]; 
            Array.Copy(inArray, outArray, inArray.Length);
            return outArray; 
        } 

        private void IncrementArgCounts() 
        {
            if (m_sizeLoc == NO_SIZE_IN_SIG)
            {
                //We don't have a size if this is a field. 
                return;
            } 
 
            m_argCount++;
        } 

        private void SetNumberOfSignatureElements(bool forceCopy)
        {
            // For most signatures, this will set the number of elements in a byte which we have reserved for it. 
            // However, if we have a field signature, we don't set the length and return.
            // If we have a signature with more than 128 arguments, we can't just set the number of elements, 
            // we actually have to allocate more space (e.g. shift everything in the array one or more spaces to the 
            // right.  We do this by making a copy of the array and leaving the correct number of blanks.  This new
            // array is now set to be m_signature and we use the AddData method to set the number of elements properly. 
            // The forceCopy argument can be used to force SetNumberOfSignatureElements to make a copy of
            // the array.  This is useful for GetSignature which promises to trim the array to be the correct size anyway.

            byte[] temp; 
            int newSigSize;
            int currSigHolder = m_currSig; 
 
            if (m_sizeLoc == NO_SIZE_IN_SIG)
                return; 

            //If we have fewer than 128 arguments and we haven't been told to copy the
            //array, we can just set the appropriate bit and return.
            if (m_argCount < 0x80 && !forceCopy) 
            {
                m_signature[m_sizeLoc] = (byte)m_argCount; 
                return; 
            }
 
            //We need to have more bytes for the size.  Figure out how many bytes here.
            //Since we need to copy anyway, we're just going to take the cost of doing a
            //new allocation.
            if (m_argCount < 0x80) 
            {
                newSigSize = 1; 
            } 
            else if (m_argCount < 0x4000)
            { 
                newSigSize = 2;
            }
            else
            { 
                newSigSize = 4;
            } 
 
            //Allocate the new array.
            temp = new byte[m_currSig + newSigSize - 1]; 

            //Copy the calling convention.  The calling convention is always just one byte
            //so we just copy that byte.  Then copy the rest of the array, shifting everything
            //to make room for the new number of elements. 
            temp[0] = m_signature[0];
            Array.Copy(m_signature, m_sizeLoc + 1, temp, m_sizeLoc + newSigSize, currSigHolder - (m_sizeLoc + 1)); 
            m_signature = temp; 

            //Use the AddData method to add the number of elements appropriately compressed. 
            m_currSig = m_sizeLoc;
            AddData(m_argCount);
            m_currSig = currSigHolder + (newSigSize - 1);
        } 

        #endregion 
 
        #region Internal Members
        internal int ArgumentCount 
        {
            get
            {
                return m_argCount; 
            }
        } 
 
        internal static bool IsSimpleType(CorElementType type)
        { 
            if (type <= CorElementType.String)
                return true;

            if (type == CorElementType.TypedByRef || type == CorElementType.I || type == CorElementType.U || type == CorElementType.Object) 
                return true;
 
            return false; 
        }
 
        internal byte[] InternalGetSignature(out int length)
        {
            // An internal method to return the signature.  Does not trim the
            // array, but passes out the length of the array in an out parameter. 
            // This is the actual array -- not a copy -- so the callee must agree
            // to not copy it. 
            // 
            // param length : an out param indicating the length of the array.
            // return : A reference to the internal ubyte array. 

            if (!m_sigDone)
            {
                m_sigDone = true; 

                // If we have more than 128 variables, we can't just set the length, we need 
                // to compress it.  Unfortunately, this means that we need to copy the entire 
                // array.  Bummer, eh?
                SetNumberOfSignatureElements(false); 
            }

            length = m_currSig;
            return m_signature; 
        }
 
 

 
        internal byte[] InternalGetSignatureArray()
        {
            int argCount = m_argCount;
            int currSigLength = m_currSig; 
            int newSigSize = currSigLength;
 
            //Allocate the new array. 
            if (argCount < 0x7F)
                newSigSize += 1; 
            else if (argCount < 0x3FFF)
                newSigSize += 2;
            else
                newSigSize += 4; 
            byte[] temp = new byte[newSigSize];
 
            // copy the sig 
            int sigCopyIndex = 0;
            // calling convention 
            temp[sigCopyIndex++] = m_signature[0];
            // arg size
            if (argCount <= 0x7F)
                temp[sigCopyIndex++] = (byte)(argCount & 0xFF); 
            else if (argCount <= 0x3FFF)
            { 
                temp[sigCopyIndex++] = (byte)((argCount >>8) | 0x80); 
                temp[sigCopyIndex++] = (byte)(argCount & 0xFF);
            } 
            else if (argCount <= 0x1FFFFFFF)
            {
                temp[sigCopyIndex++] = (byte)((argCount >>24) | 0xC0);
                temp[sigCopyIndex++] = (byte)((argCount >>16) & 0xFF); 
                temp[sigCopyIndex++] = (byte)((argCount >>8) & 0xFF);
                temp[sigCopyIndex++] = (byte)((argCount) & 0xFF); 
            } 
            else
                throw new ArgumentException(Environment.GetResourceString("Argument_LargeInteger")); 
            // copy the sig part of the sig
            Array.Copy(m_signature, 2, temp, sigCopyIndex, currSigLength - 2);
            // mark the end of sig
            temp[newSigSize - 1] = (byte)CorElementType.End; 

            return temp; 
        } 

        #endregion 

        #region Public Methods
        public void AddArgument(Type clsArgument)
        { 
            AddArgument(clsArgument, null, null);
        } 
 
        [System.Security.SecuritySafeCritical]  // auto-generated
        public void AddArgument(Type argument, bool pinned) 
        {
            if (argument == null)
                throw new ArgumentNullException("argument");
 
            IncrementArgCounts();
            AddOneArgTypeHelper(argument, pinned); 
        } 

        public void AddArguments(Type[] arguments, Type[][] requiredCustomModifiers, Type[][] optionalCustomModifiers) 
        {
            if (requiredCustomModifiers != null && (arguments == null || requiredCustomModifiers.Length != arguments.Length))
                throw new ArgumentException(Environment.GetResourceString("Argument_MismatchedArrays", "requiredCustomModifiers", "arguments"));
 
            if (optionalCustomModifiers != null && (arguments == null || optionalCustomModifiers.Length != arguments.Length))
                throw new ArgumentException(Environment.GetResourceString("Argument_MismatchedArrays", "optionalCustomModifiers", "arguments")); 
 
            if (arguments != null)
            { 
                for (int i =0; i < arguments.Length; i++)
                {
                    AddArgument(arguments[i],
                        requiredCustomModifiers == null ? null : requiredCustomModifiers[i], 
                        optionalCustomModifiers == null ? null : optionalCustomModifiers[i]);
                } 
            } 
        }
 
        [System.Security.SecuritySafeCritical]  // auto-generated
        public void AddArgument(Type argument, Type[] requiredCustomModifiers, Type[] optionalCustomModifiers)
        {
            if (m_sigDone) 
                throw new ArgumentException(Environment.GetResourceString("Argument_SigIsFinalized"));
 
            if (argument == null) 
                throw new ArgumentNullException("argument");
 
            IncrementArgCounts();

            // Add an argument to the signature. Takes a Type and determines whether it
            // is one of the primitive types of which we have special knowledge or a more 
            // general class.  In the former case, we only add the appropriate short cut encoding,
            // otherwise we will calculate proper description for the type. 
            AddOneArgTypeHelper(argument, requiredCustomModifiers, optionalCustomModifiers); 
        }
 
        public void AddSentinel()
        {
            AddElementType(CorElementType.Sentinel);
        } 

        public override bool Equals(Object obj) 
        { 
            if (!(obj is SignatureHelper))
            { 
                return false;
            }

            SignatureHelper temp = (SignatureHelper)obj; 

            if ( !temp.m_module.Equals(m_module) || temp.m_currSig!=m_currSig || temp.m_sizeLoc!=m_sizeLoc || temp.m_sigDone !=m_sigDone ) 
            { 
                return false;
            } 

            for (int i=0; i m_currSig)
            {
                byte[] temp = new byte[m_currSig];
                Array.Copy(m_signature, temp, m_currSig); 
                m_signature = temp;
            } 
 
            return m_signature;
        } 

        public override String ToString()
        {
            StringBuilder sb = new StringBuilder(); 
            sb.Append("Length: " + m_currSig + Environment.NewLine);
 
            if (m_sizeLoc != -1) 
            {
                sb.Append("Arguments: " + m_signature[m_sizeLoc] + Environment.NewLine); 
            }
            else
            {
                sb.Append("Field Signature" + Environment.NewLine); 
            }
 
            sb.Append("Signature: " + Environment.NewLine); 
            for (int i=0; i<=m_currSig; i++)
            { 
                sb.Append(m_signature[i] + "  ");
            }

            sb.Append(Environment.NewLine); 
            return sb.ToString();
        } 
 
        #endregion
 
        void _SignatureHelper.GetTypeInfoCount(out uint pcTInfo)
        {
            throw new NotImplementedException();
        } 

        void _SignatureHelper.GetTypeInfo(uint iTInfo, uint lcid, IntPtr ppTInfo) 
        { 
            throw new NotImplementedException();
        } 

        void _SignatureHelper.GetIDsOfNames([In] ref Guid riid, IntPtr rgszNames, uint cNames, uint lcid, IntPtr rgDispId)
        {
            throw new NotImplementedException(); 
        }
 
        void _SignatureHelper.Invoke(uint dispIdMember, [In] ref Guid riid, uint lcid, short wFlags, IntPtr pDispParams, IntPtr pVarResult, IntPtr pExcepInfo, IntPtr puArgErr) 
        {
            throw new NotImplementedException(); 
        }

    }
} 

 
 

 



 

 
 

 



 

 
 

 



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