StringExpressionSet.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 / Security / Util / StringExpressionSet.cs / 1305376 / StringExpressionSet.cs

                            // ==++== 
//
//   Copyright (c) Microsoft Corporation.  All rights reserved.
//
// ==--== 
// StringExpressionSet
// 
// [....] 
//
 
namespace System.Security.Util {
    using System.Text;
    using System;
    using System.Collections; 
    using System.Collections.Generic;
    using System.Runtime.CompilerServices; 
    using System.Runtime.InteropServices; 
    using System.Globalization;
    using System.Runtime.Versioning; 
    using System.IO;
    using System.Diagnostics.Contracts;

    [Serializable] 
    internal class StringExpressionSet
    { 
        protected ArrayList m_list; 
        protected bool m_ignoreCase;
        protected String m_expressions; 
        protected String[] m_expressionsArray;
        protected bool m_throwOnRelative;

        protected static readonly char[] m_separators = { ';' }; 
        protected static readonly char[] m_trimChars = { ' ' };
#if !PLATFORM_UNIX 
        protected static readonly char m_directorySeparator = '\\'; 
        protected static readonly char m_alternateDirectorySeparator = '/';
#else 
        protected static readonly char m_directorySeparator = '/';
        protected static readonly char m_alternateDirectorySeparator = '\\';
#endif // !PLATFORM_UNIX
 
        public StringExpressionSet()
            : this( true, null, false ) 
        { 
        }
 
        public StringExpressionSet( String str )
            : this( true, str, false )
        {
        } 

        public StringExpressionSet( bool ignoreCase, bool throwOnRelative ) 
            : this( ignoreCase, null, throwOnRelative ) 
        {
        } 

        [System.Security.SecuritySafeCritical]  // auto-generated
        public StringExpressionSet( bool ignoreCase, String str, bool throwOnRelative )
        { 
            m_list = null;
            m_ignoreCase = ignoreCase; 
            m_throwOnRelative = throwOnRelative; 
            if (str == null)
                m_expressions = null; 
            else
            AddExpressions( str );
        }
 
        protected virtual StringExpressionSet CreateNewEmpty()
        { 
            return new StringExpressionSet(); 
        }
 
        public virtual StringExpressionSet Copy()
        {
            StringExpressionSet copy = CreateNewEmpty();
            if (this.m_list != null) 
                copy.m_list = new ArrayList(this.m_list);
            copy.m_expressions = this.m_expressions; 
            copy.m_ignoreCase = this.m_ignoreCase; 
            copy.m_throwOnRelative = this.m_throwOnRelative;
            return copy; 
        }

        public void SetThrowOnRelative( bool throwOnRelative )
        { 
            this.m_throwOnRelative = throwOnRelative;
        } 
 
        private static String StaticProcessWholeString( String str )
        { 
            return str.Replace( m_alternateDirectorySeparator, m_directorySeparator );
        }

        private static String StaticProcessSingleString( String str ) 
        {
            return str.Trim( m_trimChars ); 
        } 

        protected virtual String ProcessWholeString( String str ) 
        {
            return StaticProcessWholeString(str);
        }
 
        protected virtual String ProcessSingleString( String str )
        { 
            return StaticProcessSingleString(str); 
        }
 
        [System.Security.SecurityCritical]  // auto-generated
        [ResourceExposure(ResourceScope.None)]
        [ResourceConsumption(ResourceScope.Machine, ResourceScope.Machine)]
        public void AddExpressions( String str ) 
        {
            if (str == null) 
                throw new ArgumentNullException( "str" ); 
            Contract.EndContractBlock();
            if (str.Length == 0) 
                return;

            str = ProcessWholeString( str );
 
            if (m_expressions == null)
                m_expressions = str; 
            else 
                m_expressions = m_expressions + m_separators[0] + str;
 
            m_expressionsArray = null;

            // We have to parse the string and compute the list here.
            // The logic in this class tries to delay this parsing but 
            // since operations like IsSubsetOf are called during
            // demand evaluation, it is not safe to delay this step 
            // as that would cause concurring threads to update the object 
            // at the same time. The CheckList operation should ideally be
            // removed from this class, but for the sake of keeping the 
            // changes to a minimum here, we simply make sure m_list
            // cannot be null by parsing m_expressions eagerly.

            String[] arystr = Split( str ); 

            if (m_list == null) 
                m_list = new ArrayList(); 

            for (int index = 0; index < arystr.Length; ++index) 
            {
                if (arystr[index] != null && !arystr[index].Equals( "" ))
                {
                    String temp = ProcessSingleString( arystr[index] ); 
                    int indexOfNull = temp.IndexOf( '\0' );
 
                    if (indexOfNull != -1) 
                        temp = temp.Substring( 0, indexOfNull );
 
                    if (temp != null && !temp.Equals( "" ))
                    {
                        if (m_throwOnRelative)
                        { 
                            if (Path.IsRelative(temp))
                            { 
                                throw new ArgumentException( Environment.GetResourceString( "Argument_AbsolutePathRequired" ) ); 
                            }
 
                            temp = CanonicalizePath( temp );
                        }

                        m_list.Add( temp ); 
                    }
                } 
            } 

            Reduce(); 
        }

        [System.Security.SecurityCritical]  // auto-generated
        public void AddExpressions( String[] str, bool checkForDuplicates, bool needFullPath ) 
        {
            AddExpressions(CreateListFromExpressions(str, needFullPath), checkForDuplicates); 
        } 

        [System.Security.SecurityCritical]  // auto-generated 
        public void AddExpressions( ArrayList exprArrayList, bool checkForDuplicates)
        {
            Contract.Assert( m_throwOnRelative, "This should only be called when throw on relative is set" );
 
            m_expressionsArray = null;
            m_expressions = null; 
 
            if (m_list != null)
                m_list.AddRange(exprArrayList); 
            else
                m_list = new ArrayList(exprArrayList);

            if (checkForDuplicates) 
                Reduce();
        } 
 

        [System.Security.SecurityCritical]  // auto-generated 
        [ResourceExposure(ResourceScope.None)]
        [ResourceConsumption(ResourceScope.Machine, ResourceScope.Machine)]
        internal static ArrayList CreateListFromExpressions(String[] str, bool needFullPath)
        { 
            if (str == null)
            { 
                throw new ArgumentNullException( "str" ); 
            }
            Contract.EndContractBlock(); 
            ArrayList retArrayList = new ArrayList();
            for (int index = 0; index < str.Length; ++index)
            {
                if (str[index] == null) 
                    throw new ArgumentNullException( "str" );
 
                String oneString = StaticProcessWholeString( str[index] ); 

                if (oneString != null && oneString.Length != 0) 
                {
                    String temp = StaticProcessSingleString( oneString);

                    int indexOfNull = temp.IndexOf( '\0' ); 

                    if (indexOfNull != -1) 
                        temp = temp.Substring( 0, indexOfNull ); 

                    if (temp != null && temp.Length != 0) 
                    {
                        if (Path.IsRelative(temp))
                        {
                            throw new ArgumentException( Environment.GetResourceString( "Argument_AbsolutePathRequired" ) ); 
                        }
 
                        temp = CanonicalizePath( temp, needFullPath ); 

 
                        retArrayList.Add( temp );
                    }
                }
            } 

            return retArrayList; 
        } 

        [System.Security.SecurityCritical]  // auto-generated 
        protected void CheckList()
        {
            if (m_list == null && m_expressions != null)
            { 
                CreateList();
            } 
        } 

        protected String[] Split( String expressions ) 
        {
            if (m_throwOnRelative)
            {
                List tempList = new List(); 

                String[] quoteSplit = expressions.Split( '\"' ); 
 
                for (int i = 0; i < quoteSplit.Length; ++i)
                { 
                    if (i % 2 == 0)
                    {
                        String[] semiSplit = quoteSplit[i].Split( ';' );
 
                        for (int j = 0; j < semiSplit.Length; ++j)
                        { 
                            if (semiSplit[j] != null && !semiSplit[j].Equals( "" )) 
                                tempList.Add( semiSplit[j] );
                        } 
                    }
                    else
                    {
                        tempList.Add( quoteSplit[i] ); 
                    }
                } 
 
                String[] finalArray = new String[tempList.Count];
 
                IEnumerator enumerator = tempList.GetEnumerator();

                int index = 0;
                while (enumerator.MoveNext()) 
                {
                    finalArray[index++] = (String)enumerator.Current; 
                } 

                return finalArray; 
            }
            else
            {
                return expressions.Split( m_separators ); 
            }
        } 
 

        [System.Security.SecurityCritical]  // auto-generated 
        [ResourceExposure(ResourceScope.None)]
        [ResourceConsumption(ResourceScope.Machine, ResourceScope.Machine)]
        protected void CreateList()
        { 
            String[] expressionsArray = Split( m_expressions );
 
            m_list = new ArrayList(); 

            for (int index = 0; index < expressionsArray.Length; ++index) 
            {
                if (expressionsArray[index] != null && !expressionsArray[index].Equals( "" ))
                {
                    String temp = ProcessSingleString( expressionsArray[index] ); 

                    int indexOfNull = temp.IndexOf( '\0' ); 
 
                    if (indexOfNull != -1)
                        temp = temp.Substring( 0, indexOfNull ); 

                    if (temp != null && !temp.Equals( "" ))
                    {
                        if (m_throwOnRelative) 
                        {
                            if (Path.IsRelative(temp)) 
                            { 
                                throw new ArgumentException( Environment.GetResourceString( "Argument_AbsolutePathRequired" ) );
                            } 

                            temp = CanonicalizePath( temp );
                        }
 
                        m_list.Add( temp );
                    } 
                } 
            }
        } 

        public bool IsEmpty()
        {
            if (m_list == null) 
            {
                return m_expressions == null; 
            } 
            else
            { 
                return m_list.Count == 0;
            }
        }
 
        [System.Security.SecurityCritical]  // auto-generated
        public bool IsSubsetOf( StringExpressionSet ses ) 
        { 
            if (this.IsEmpty())
                return true; 

            if (ses == null || ses.IsEmpty())
                return false;
 
            CheckList();
            ses.CheckList(); 
 
            for (int index = 0; index < this.m_list.Count; ++index)
            { 
                if (!StringSubsetStringExpression( (String)this.m_list[index], ses, m_ignoreCase ))
                {
                    return false;
                } 
            }
            return true; 
        } 

        [System.Security.SecurityCritical]  // auto-generated 
        public bool IsSubsetOfPathDiscovery( StringExpressionSet ses )
        {
            if (this.IsEmpty())
                return true; 

            if (ses == null || ses.IsEmpty()) 
                return false; 

            CheckList(); 
            ses.CheckList();

            for (int index = 0; index < this.m_list.Count; ++index)
            { 
                if (!StringSubsetStringExpressionPathDiscovery( (String)this.m_list[index], ses, m_ignoreCase ))
                { 
                    return false; 
                }
            } 
            return true;
        }

 
        [System.Security.SecurityCritical]  // auto-generated
        public StringExpressionSet Union( StringExpressionSet ses ) 
        { 
            // If either set is empty, the union represents a copy of the other.
 
            if (ses == null || ses.IsEmpty())
                return this.Copy();

            if (this.IsEmpty()) 
                return ses.Copy();
 
            CheckList(); 
            ses.CheckList();
 
            // Perform the union
            // note: insert smaller set into bigger set to reduce needed comparisons

            StringExpressionSet bigger = ses.m_list.Count > this.m_list.Count ? ses : this; 
            StringExpressionSet smaller = ses.m_list.Count <= this.m_list.Count ? ses : this;
 
            StringExpressionSet unionSet = bigger.Copy(); 

            unionSet.Reduce(); 

            for (int index = 0; index < smaller.m_list.Count; ++index)
            {
                unionSet.AddSingleExpressionNoDuplicates( (String)smaller.m_list[index] ); 
            }
 
            unionSet.GenerateString(); 

            return unionSet; 
        }


        [System.Security.SecurityCritical]  // auto-generated 
        public StringExpressionSet Intersect( StringExpressionSet ses )
        { 
            // If either set is empty, the intersection is empty 

            if (this.IsEmpty() || ses == null || ses.IsEmpty()) 
                return CreateNewEmpty();

            CheckList();
            ses.CheckList(); 

            // Do the intersection for real 
 
            StringExpressionSet intersectSet = CreateNewEmpty();
 
            for (int this_index = 0; this_index < this.m_list.Count; ++this_index)
            {
                for (int ses_index = 0; ses_index < ses.m_list.Count; ++ses_index)
                { 
                    if (StringSubsetString( (String)this.m_list[this_index], (String)ses.m_list[ses_index], m_ignoreCase ))
                    { 
                        if (intersectSet.m_list == null) 
                        {
                            intersectSet.m_list = new ArrayList(); 
                        }
                        intersectSet.AddSingleExpressionNoDuplicates( (String)this.m_list[this_index] );
                    }
                    else if (StringSubsetString( (String)ses.m_list[ses_index], (String)this.m_list[this_index], m_ignoreCase )) 
                    {
                        if (intersectSet.m_list == null) 
                        { 
                            intersectSet.m_list = new ArrayList();
                        } 
                        intersectSet.AddSingleExpressionNoDuplicates( (String)ses.m_list[ses_index] );
                    }
                }
            } 

            intersectSet.GenerateString(); 
 
            return intersectSet;
        } 

        protected void GenerateString()
        {
            if (m_list != null) 
            {
                StringBuilder sb = new StringBuilder(); 
 
                IEnumerator enumerator = this.m_list.GetEnumerator();
                bool first = true; 

                while (enumerator.MoveNext())
                {
                    if (!first) 
                        sb.Append( m_separators[0] );
                    else 
                        first = false; 

                    String currentString = (String)enumerator.Current; 
                    if (currentString != null)
                    {
                        int indexOfSeparator = currentString.IndexOf( m_separators[0] );
 
                        if (indexOfSeparator != -1)
                            sb.Append( '\"' ); 
 
                        sb.Append( currentString );
 
                        if (indexOfSeparator != -1)
                            sb.Append( '\"' );
                    }
                } 

                m_expressions = sb.ToString(); 
            } 
            else
            { 
                m_expressions = null;
            }
        }
 
        [System.Security.SecuritySafeCritical]  // auto-generated
        public override String ToString() 
        { 
            CheckList();
 
            Reduce();

            GenerateString();
 
            return m_expressions;
        } 
 
        public String[] ToStringArray()
        { 
            if (m_expressionsArray == null && m_list != null)
            {
                m_expressionsArray = (String[])m_list.ToArray(typeof(String));
            } 

            return m_expressionsArray; 
        } 

 
        //-------------------------------
        // protected static helper functions
        //-------------------------------
 

        protected bool StringSubsetStringExpression( String left, StringExpressionSet right, bool ignoreCase ) 
        { 
            for (int index = 0; index < right.m_list.Count; ++index)
            { 
                if (StringSubsetString( left, (String)right.m_list[index], ignoreCase ))
                {
                    return true;
                } 
            }
            return false; 
        } 

        protected static bool StringSubsetStringExpressionPathDiscovery( String left, StringExpressionSet right, bool ignoreCase ) 
        {
            for (int index = 0; index < right.m_list.Count; ++index)
            {
                if (StringSubsetStringPathDiscovery( left, (String)right.m_list[index], ignoreCase )) 
                {
                    return true; 
                } 
            }
            return false; 
        }


        protected virtual bool StringSubsetString( String left, String right, bool ignoreCase ) 
        {
            StringComparison strComp = (ignoreCase ? StringComparison.OrdinalIgnoreCase : StringComparison.Ordinal); 
            if (right == null || left == null || right.Length == 0 || left.Length == 0 || 
                right.Length > left.Length)
            { 
                return false;
            }
            else if (right.Length == left.Length)
            { 
                // if they are equal in length, just do a normal compare
                return String.Compare( right, left, strComp) == 0; 
            } 
            else if (left.Length - right.Length == 1 && left[left.Length-1] == m_directorySeparator)
            { 
                return String.Compare( left, 0, right, 0, right.Length, strComp) == 0;
            }
            else if (right[right.Length-1] == m_directorySeparator)
            { 
                // right is definitely a directory, just do a substring compare
                return String.Compare( right, 0, left, 0, right.Length, strComp) == 0; 
            } 
            else if (left[right.Length] == m_directorySeparator)
            { 
                // left is hinting at being a subdirectory on right, do substring compare to make find out
                return String.Compare( right, 0, left, 0, right.Length, strComp) == 0;
            }
            else 
            {
                return false; 
            } 
        }
 
        protected static bool StringSubsetStringPathDiscovery( String left, String right, bool ignoreCase )
        {
            StringComparison strComp = (ignoreCase ? StringComparison.OrdinalIgnoreCase : StringComparison.Ordinal);
            if (right == null || left == null || right.Length == 0 || left.Length == 0) 
            {
                return false; 
            } 
            else if (right.Length == left.Length)
            { 
                // if they are equal in length, just do a normal compare
                return String.Compare( right, left, strComp) == 0;
            }
            else 
            {
                String shortString, longString; 
 
                if (right.Length < left.Length)
                { 
                    shortString = right;
                    longString = left;
                }
                else 
                {
                    shortString = left; 
                    longString = right; 
                }
 
                if (String.Compare( shortString, 0, longString, 0, shortString.Length, strComp) != 0)
                {
                    return false;
                } 

#if !PLATFORM_UNIX 
                if (shortString.Length == 3 && 
                    shortString.EndsWith( ":\\", StringComparison.Ordinal ) &&
                    ((shortString[0] >= 'A' && shortString[0] <= 'Z') || 
                    (shortString[0] >= 'a' && shortString[0] <= 'z')))
#else
                if (shortString.Length == 1 && shortString[0]== m_directorySeparator)
#endif // !PLATFORM_UNIX 
                     return true;
 
                return longString[shortString.Length] == m_directorySeparator; 
            }
        } 


        //-------------------------------
        // protected helper functions 
        //-------------------------------
 
        protected void AddSingleExpressionNoDuplicates( String expression ) 
        {
            int index = 0; 

            m_expressionsArray = null;
            m_expressions = null;
 
            if (this.m_list == null)
                this.m_list = new ArrayList(); 
 
            while (index < this.m_list.Count)
            { 
                if (StringSubsetString( (String)this.m_list[index], expression, m_ignoreCase ))
                {
                    this.m_list.RemoveAt( index );
                } 
                else if (StringSubsetString( expression, (String)this.m_list[index], m_ignoreCase ))
                { 
                    return; 
                }
                else 
                {
                    index++;
                }
            } 
            this.m_list.Add( expression );
        } 
 
        [System.Security.SecurityCritical]  // auto-generated
        protected void Reduce() 
        {
            CheckList();

            if (this.m_list == null) 
                return;
 
            int j; 

            for (int i = 0; i < this.m_list.Count - 1; i++) 
            {
                j = i + 1;

                while (j < this.m_list.Count) 
                {
                    if (StringSubsetString( (String)this.m_list[j], (String)this.m_list[i], m_ignoreCase )) 
                    { 
                        this.m_list.RemoveAt( j );
                    } 
                    else if (StringSubsetString( (String)this.m_list[i], (String)this.m_list[j], m_ignoreCase ))
                    {
                        // write the value at j into position i, delete the value at position j and keep going.
                        this.m_list[i] = this.m_list[j]; 
                        this.m_list.RemoveAt( j );
                        j = i + 1; 
                    } 
                    else
                    { 
                        j++;
                    }
                }
            } 
        }
 
        [System.Security.SecurityCritical]  // auto-generated 
        [ResourceExposure(ResourceScope.Machine)]
        [DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode)] 
        [SuppressUnmanagedCodeSecurity]
        internal static extern void GetLongPathName( String path, StringHandleOnStack retLongPath );

        [System.Security.SecurityCritical]  // auto-generated 
        [ResourceExposure(ResourceScope.Machine)]
        [ResourceConsumption(ResourceScope.Machine)] 
        internal static String CanonicalizePath( String path ) 
        {
            return CanonicalizePath( path, true ); 
        }

        [System.Security.SecurityCritical]  // auto-generated
        [ResourceExposure(ResourceScope.Machine)] 
        [ResourceConsumption(ResourceScope.Machine)]
        internal static String CanonicalizePath( String path, bool needFullPath ) 
        { 

#if !PLATFORM_UNIX 
            if (path.IndexOf( '~' ) != -1)
            {
                string longPath = null;
                GetLongPathName(path, JitHelpers.GetStringHandleOnStack(ref longPath)); 
                path = (longPath != null) ? longPath : path;
            } 
 
            if (path.IndexOf( ':', 2 ) != -1)
                throw new NotSupportedException( Environment.GetResourceString( "Argument_PathFormatNotSupported" ) ); 
#endif // !PLATFORM_UNIX

            if (needFullPath)
            { 
                String newPath = System.IO.Path.GetFullPathInternal( path );
                if (path.EndsWith( m_directorySeparator + ".", StringComparison.Ordinal )) 
                { 
                    if (newPath.EndsWith( m_directorySeparator ))
                    { 
                        newPath += ".";
                    }
                    else
                    { 
                        newPath += m_directorySeparator + ".";
                    } 
                } 
                return newPath;
            } 
            else
                return path;
        }
    } 
}

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