TypeSystemHelpers.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 / cdf / src / WF / Activities / Common / TypeSystemHelpers.cs / 1305376 / TypeSystemHelpers.cs

                            // Copyright (c) Microsoft Corporation. All rights reserved. 
//
// THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND,
// WHETHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED
// WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR PURPOSE. 
// THE ENTIRE RISK OF USE OR RESULTS IN CONNECTION WITH THE USE OF THIS CODE
// AND INFORMATION REMAINS WITH THE USER. 
// 

/********************************************************************** 
 * NOTE: A copy of this file exists at: WF\Common\Shared
 * The two files must be kept in [....].  Any change made here must also
 * be made to WF\Common\Shared\TypeSystemHelpers.cs
*********************************************************************/ 
namespace System.Workflow.Activities.Common
{ 
    using System; 
    using System.Collections;
    using System.Collections.Specialized; 
    using System.Collections.Generic;
    using System.Globalization;
    using System.Reflection;
    using System.CodeDom; 
    using System.Text.RegularExpressions;
    using System.Diagnostics.CodeAnalysis; 
    using System.Workflow.ComponentModel.Compiler; 

    internal static class ParseHelpers 
    {
        private static readonly Version emptyVersion		= new Version(0, 0, 0, 0);
        private const string			VersionTag			= "version";
        private const string			CultureTag			= "culture"; 
        private const string			PublicKeyTokenTag	= "publickeytoken";
 
        private static readonly ArrayList VBKeywords = new ArrayList(new string[] {"Integer", "String", "Boolean", "Object", "Void", "Single", "Double", "Char", "DateTime", "Long", "Byte", "Short", "Single", "Double", "Decimal", "UInteger", "ULong", "SByte", "UShort" }); 
        private static readonly ArrayList CSKeywords = new ArrayList(new string[] {"int", "string", "bool", "object", "void", "float", "double", "char", "Date", "long", "byte", "short", "Single", "double", "decimal", "uint", "ulong", "sbyte", "ushort" });
        private static readonly string[] DotNetKeywords = new string[] 
            {"System.Int32", "System.String", "System.Boolean", "System.Object", "System.Void", "System.Single", "System.Double", "System.Char", "System.DateTime", "System.Int64", "System.Byte", "System.Int16", "System.Single", "System.Double", "System.Decimal", "System.UInt32", "System.UInt64", "System.SByte", "System.UInt16"  };

        internal enum ParseTypeNameLanguage
        { 
            VB,
            CSharp, 
            NetFramework 
        }
 
        [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
        internal static bool ParseTypeName(string inputTypeName, ParseTypeNameLanguage parseTypeNameLanguage, out string typeName, out string[] parameters, out string elemantDecorator)
        {
            typeName = string.Empty; 
            parameters = null;
            elemantDecorator = string.Empty; 
 
            // replace all language specific array\generic chars with the net-framework's representation
            if (parseTypeNameLanguage == ParseTypeNameLanguage.VB) 
                inputTypeName = inputTypeName.Replace('(', '[').Replace(')', ']');
            else if (parseTypeNameLanguage == ParseTypeNameLanguage.CSharp)
                inputTypeName = inputTypeName.Replace('<', '[').Replace('>', ']');
 
            int endIndex = inputTypeName.LastIndexOfAny(new char[] { ']', '&', '*' });
            if (endIndex == -1) 
            { 
                // "simple" type
                typeName = inputTypeName; 
            }
            else if (inputTypeName[endIndex] == ']') //array or generic
            {
                int startIndex = endIndex; 
                int nestLevel = 1;
                while ((startIndex > 0) && (nestLevel > 0)) 
                { 
                    startIndex--;
                    if (inputTypeName[startIndex] == ']') 
                        nestLevel++;
                    else if (inputTypeName[startIndex] == '[')
                        nestLevel--;
                } 
                if (nestLevel != 0)
                    return false; 
 
                typeName = inputTypeName.Substring(0, startIndex) + inputTypeName.Substring(endIndex + 1);
 
                string bracketContent = inputTypeName.Substring(startIndex + 1, endIndex - startIndex - 1).Trim();
                if ((bracketContent == String.Empty) || (bracketContent.TrimStart()[0] == ','))
                {
                    // array 
                    elemantDecorator = "[" + bracketContent + "]";
                } 
                else 
                {
                    // Isolate the parameters (looking for commas alone will not cover cases 
                    // when parameters are multi-dim array or generics...
                    int nestingLevel = 0;
                    char[] genericParamChars = bracketContent.ToCharArray();
                    for (int loop = 0; loop < genericParamChars.Length; loop++) 
                    {
                        if (genericParamChars[loop] == '[') 
                            nestingLevel++; 
                        else if (genericParamChars[loop] == ']')
                            nestingLevel--; 
                        else if ((genericParamChars[loop] == ',') && (nestingLevel == 0))
                            genericParamChars[loop] = '$';
                    }
                    // split to get the list of generic arguments 
                    parameters = new string(genericParamChars).Split(new char[] { '$' });
 
                    // clean the parameters 
                    for (int loop = 0; loop < parameters.Length; loop++)
                    { 
                        parameters[loop] = parameters[loop].Trim();

                        // remove extra brackects if exist
                        if (parameters[loop][0] == '[') 
                            parameters[loop] = parameters[loop].Substring(1, parameters[loop].Length - 2);
 
                        // remove the "Of " keyword form VB parameters 
                        if ((parseTypeNameLanguage == ParseTypeNameLanguage.VB) && (parameters[loop].StartsWith("Of ", StringComparison.OrdinalIgnoreCase)))
                            parameters[loop] = parameters[loop].Substring(3).TrimStart(); 
                    }
                }
            }
            else // byref, pointer 
            {
                typeName = inputTypeName.Substring(0, endIndex) + inputTypeName.Substring(endIndex + 1); 
                elemantDecorator = inputTypeName.Substring(endIndex, 1); 
            }
 
            //Work around: we need to account for these langugue keywords and provide the correct type for them.
            //      A tighter way to achieve this should be found.
            if ((parseTypeNameLanguage == ParseTypeNameLanguage.CSharp) && CSKeywords.Contains(typeName))
                typeName = DotNetKeywords[CSKeywords.IndexOf(typeName)]; 
            else if ((parseTypeNameLanguage == ParseTypeNameLanguage.VB) && VBKeywords.Contains(typeName))
                typeName = DotNetKeywords[VBKeywords.IndexOf(typeName)]; 
 
            return true;
        } 

        internal static bool AssemblyNameEquals(AssemblyName thisName, AssemblyName thatName)
        {
            // Simplest check -- the assembly name must match. 
            if (thisName.Name == null || thatName.Name == null)
                return false; 
 
            if (!thatName.Name.Equals(thisName.Name))
                return false; 

            // Next, version checks.  We are comparing AGAINST thatName,
            // so if thatName has a version defined, we must match.
            Version thatVersion = thatName.Version; 
            if (thatVersion != null && thatVersion != emptyVersion && thatVersion != thisName.Version)
                return false; 
 
            // Same story for culture
            CultureInfo thatCulture = thatName.CultureInfo; 
            if (thatCulture != null && !thatCulture.Equals(CultureInfo.InvariantCulture))
            {
                CultureInfo thisCulture = thisName.CultureInfo;
                if (thisCulture == null) 
                    return false;
 
                // the requested culture must either equal, or be a parent of 
                // our culture.
                do 
                {
                    if (thatCulture.Equals(thisCulture))
                        break;
                    thisCulture = thisCulture.Parent; 
                    if (thisCulture.Equals(CultureInfo.InvariantCulture))
                        return false; 
                } while (true); 
            }
 
            // And the same thing for the public token
            byte[] thatToken = thatName.GetPublicKeyToken();
            if (thatToken != null && thatToken.Length != 0)
            { 
                byte[] thisToken = thisName.GetPublicKeyToken();
                if (thisToken == null) 
                    return false; 
                if (thatToken.Length != thisToken.Length)
                    return false; 
                for (int i = 0; i < thatToken.Length; i++)
                {
                    if (thatToken[i] != thisToken[i])
                        return false; 
                }
            } 
            return true; 
        }
 
        [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
        internal static bool AssemblyNameEquals(AssemblyName thisName, string thatName)
        {
            if (thisName == null || string.IsNullOrEmpty(thisName.Name)) 
                return false;
            if (string.IsNullOrEmpty(thatName)) 
                return false; 

            string[] parts = thatName.Split(','); 
            if (parts.Length == 0)
                return false;

            string thatAssemblyName = parts[0].Trim(); 
            if (!thatAssemblyName.Equals(thisName.Name))
                return false; 
 
            if (parts.Length == 1)
                return true; 

            Version		thatVersion = null;
            CultureInfo thatCulture = null;
            byte[]		thatToken = null; 
            for (int index = 1; index < parts.Length; index++)
            { 
                int indexOfEquals = parts[index].IndexOf('='); 
                if (indexOfEquals != -1)
                { 
                    string partName = parts[index].Substring(0, indexOfEquals).Trim().ToLowerInvariant();
                    string partValue = parts[index].Substring(indexOfEquals + 1).Trim().ToLowerInvariant();
                    if (string.IsNullOrEmpty(partValue))
                        continue; 

                    switch (partName) 
                    { 
                        case ParseHelpers.VersionTag:
                            thatVersion = new Version(partValue); 
                            break;
                        case ParseHelpers.CultureTag:
                            if (!string.Equals(partValue, "neutral", StringComparison.OrdinalIgnoreCase))
                                thatCulture = new CultureInfo(partValue); 
                            break;
                        case ParseHelpers.PublicKeyTokenTag: 
                            if (!string.Equals(partValue, "null", StringComparison.OrdinalIgnoreCase)) 
                            {
                                thatToken = new byte[partValue.Length / 2]; 
                                for (int i = 0; i < thatToken.Length; i++)
                                    thatToken[i] = Byte.Parse(partValue.Substring(i * 2, 2), NumberStyles.HexNumber, CultureInfo.InvariantCulture);
                            }
                            break; 
                        default:
                            break; 
                    } 
                }
            } 

            if (thatVersion != null && thatVersion != emptyVersion && thatVersion != thisName.Version)
                return false;
 
            if (thatCulture != null && !thatCulture.Equals(CultureInfo.InvariantCulture))
            { 
                CultureInfo thisCulture = thisName.CultureInfo; 
                if (thisCulture == null)
                    return false; 

                // the requested culture must either equal, or be a parent of
                // our culture.
                do 
                {
                    if (thatCulture.Equals(thisCulture)) 
                        break; 
                    thisCulture = thisCulture.Parent;
                    if (thisCulture.Equals(CultureInfo.InvariantCulture)) 
                        return false;
                } while (true);
            }
 
            if (thatToken != null && thatToken.Length != 0)
            { 
                byte[] thisToken = thisName.GetPublicKeyToken(); 
                if (thisToken == null)
                    return false; 
                if (thatToken.Length != thisToken.Length)
                    return false;
                for (int i = 0; i < thatToken.Length; i++)
                { 
                    if (thatToken[i] != thisToken[i])
                        return false; 
                } 
            }
 
            return true;
        }

        [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] 
        internal static string FormatType(Type type, SupportedLanguages language)
        { 
            string typeName = string.Empty; 
            if (type.IsArray)
            { 
                typeName = FormatType(type.GetElementType(), language);
                if (language == SupportedLanguages.CSharp)
                    typeName += '[';
                else 
                    typeName += '(';
 
                typeName += new string(',', type.GetArrayRank() - 1); 
                if (language == SupportedLanguages.CSharp)
                    typeName += ']'; 
                else
                    typeName += ')';
            }
            else 
            {
                typeName = type.FullName; 
                int indexOfSpecialChar = typeName.IndexOf('`'); 
                if (indexOfSpecialChar != -1)
                    typeName = typeName.Substring(0, indexOfSpecialChar); 
                typeName = typeName.Replace('+', '.');

                if (type.ContainsGenericParameters || type.IsGenericType)
                { 
                    Type[] genericArguments = type.GetGenericArguments();
                    if (language == SupportedLanguages.CSharp) 
                        typeName += '<'; 
                    else
                        typeName += '('; 

                    bool first = true;
                    foreach (Type genericArgument in genericArguments)
                    { 
                        if (!first)
                            typeName += ", "; 
                        else 
                        {
                            if (language == SupportedLanguages.VB) 
                                typeName += "Of ";
                            first = false;
                        }
                        typeName += FormatType(genericArgument, language); 
                    }
 
                    if (language == SupportedLanguages.CSharp) 
                        typeName += '>';
                    else 
                        typeName += ')';
                }
            }
            return typeName; 
        }
 
        // Helper method to format a type name (language invariant) to a specific language 
        [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
        internal static string FormatType(string type, SupportedLanguages language) 
        {
            string formattedType = string.Empty;
            string[] genericParamTypeNames = null;
            string baseTypeName = string.Empty; 
            string elementDecorators = string.Empty;
            if (ParseHelpers.ParseTypeName(type, ParseHelpers.ParseTypeNameLanguage.NetFramework, out baseTypeName, out genericParamTypeNames, out elementDecorators)) 
            { 
                if (elementDecorators.Length > 0)
                { 
                    // VB uses '()' for arrays
                    if (language == SupportedLanguages.VB)
                        elementDecorators = elementDecorators.Replace('[', '(').Replace(']', ')');
 
                    formattedType = FormatType(baseTypeName, language) + elementDecorators;
                } 
                else if (genericParamTypeNames != null && genericParamTypeNames.Length > 0) 
                {
                    // add generic type 
                    formattedType = FormatType(baseTypeName, language);

                    // add generic arguments
                    if (language == SupportedLanguages.CSharp) 
                        formattedType += '<';
                    else 
                        formattedType += '('; 

                    bool first = true; 
                    foreach (string genericArgument in genericParamTypeNames)
                    {
                        if (!first)
                            formattedType += ", "; 
                        else
                        { 
                            if (language == SupportedLanguages.VB) 
                                formattedType += "Of ";
                            first = false; 
                        }

                        formattedType += FormatType(genericArgument, language);
                    } 

                    if (language == SupportedLanguages.CSharp) 
                        formattedType += '>'; 
                    else
                        formattedType += ')'; 
                }
                else
                {
                    // non generic, non decorated type - simple cleanup 
                    formattedType = baseTypeName.Replace('+', '.');
 
                    int indexOfSpecialChar = formattedType.IndexOf('`'); 
                    if (indexOfSpecialChar != -1)
                        formattedType = formattedType.Substring(0, indexOfSpecialChar); 

                    indexOfSpecialChar = formattedType.IndexOf(',');
                    if (indexOfSpecialChar != -1)
                        formattedType = formattedType.Substring(0, indexOfSpecialChar); 

                } 
            } 

            return formattedType; 
        }

        [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
        internal static Type ParseTypeName(ITypeProvider typeProvider, SupportedLanguages language, string typeName) 
        {
            Type returnType = null; 
 
            returnType = typeProvider.GetType(typeName, false);
            if (returnType == null) 
            {
                string simpleTypeName = String.Empty;
                string decoratorString = String.Empty;
                string[] parameters = null; 
                if (ParseTypeName(typeName, language == SupportedLanguages.CSharp ? ParseTypeNameLanguage.CSharp : ParseTypeNameLanguage.VB , out simpleTypeName, out parameters, out decoratorString))
                { 
                    returnType = typeProvider.GetType(simpleTypeName + decoratorString, false); 
                }
            } 

            return returnType;
        }
    } 
}

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