Code:
/ Dotnetfx_Vista_SP2 / Dotnetfx_Vista_SP2 / 8.0.50727.4016 / DEVDIV / depot / DevDiv / releases / whidbey / NetFxQFE / ndp / clr / src / BCL / System / Security / Util / StringExpressionSet.cs / 1 / StringExpressionSet.cs
// ==++== // // Copyright (c) Microsoft Corporation. All rights reserved. // // ==--== // StringExpressionSet // namespace System.Security.Util { using System.Text; using System; using System.Collections; using System.Runtime.CompilerServices; using System.Globalization; using System.Runtime.Versioning; [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 ) { } 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); } public void AddExpressions( String str ) { if (str == null) throw new ArgumentNullException( "str" ); 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 !PLATFORM_UNIX if (!((temp.Length >= 3 && temp[1] == ':' && temp[2] == '\\' && ((temp[0] >= 'a' && temp[0] <= 'z') || (temp[0] >= 'A' && temp[0] <= 'Z'))) || (temp.Length >= 2 && temp[0] == '\\' && temp[1] == '\\'))) #else if(!(temp.Length >= 1 && temp[0] == m_directorySeparator)) #endif // !PLATFORM_UNIX { throw new ArgumentException( Environment.GetResourceString( "Argument_AbsolutePathRequired" ) ); } temp = CanonicalizePath( temp ); } m_list.Add( temp ); } } } Reduce(); } public void AddExpressions( String[] str, bool checkForDuplicates, bool needFullPath ) { AddExpressions(CreateListFromExpressions(str, needFullPath), checkForDuplicates); } public void AddExpressions( ArrayList exprArrayList, bool checkForDuplicates) { BCLDebug.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(); } internal static ArrayList CreateListFromExpressions(String[] str, bool needFullPath) { if (str == null) { throw new ArgumentNullException( "str" ); } 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 !PLATFORM_UNIX if (!((temp.Length >= 3 && temp[1] == ':' && temp[2] == '\\' && ((temp[0] >= 'a' && temp[0] <= 'z') || (temp[0] >= 'A' && temp[0] <= 'Z'))) || (temp.Length >= 2 && temp[0] == '\\' && temp[1] == '\\'))) #else if(!(temp.Length >= 1 && temp[0] == m_directorySeparator)) #endif // !PLATFORM_UNIX { throw new ArgumentException( Environment.GetResourceString( "Argument_AbsolutePathRequired" ) ); } temp = CanonicalizePath( temp, needFullPath ); retArrayList.Add( temp ); } } } return retArrayList; } protected void CheckList() { if (m_list == null && m_expressions != null) { CreateList(); } } protected String[] Split( String expressions ) { if (m_throwOnRelative) { ArrayList tempList = new ArrayList(); 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 ); } } 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 !PLATFORM_UNIX if (!((temp.Length >= 3 && temp[1] == ':' && temp[2] == '\\' && ((temp[0] >= 'a' && temp[0] <= 'z') || (temp[0] >= 'A' && temp[0] <= 'Z'))) || (temp.Length >= 2 && temp[0] == '\\' && temp[1] == '\\'))) #else if(!(temp.Length >= 1 && temp[0] == m_directorySeparator)) #endif // !PLATFORM_UNIX { 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; } } 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; } 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; } 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; } 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; } } 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 ); } 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++; } } } } [MethodImplAttribute(MethodImplOptions.InternalCall)] internal static extern String GetLongPathName( String path ); internal static String CanonicalizePath( String path ) { return CanonicalizePath( path, true ); } [ResourceExposure(ResourceScope.None)] // All internal, for string comparisons [ResourceConsumption(ResourceScope.Machine, ResourceScope.Machine)] internal static String CanonicalizePath( String path, bool needFullPath ) { #if !PLATFORM_UNIX if (path.IndexOf( '~' ) != -1) path = GetLongPathName( 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 !FEATURE_PAL if (path.EndsWith( "\\.", StringComparison.Ordinal )) { if (newPath.EndsWith( "\\", StringComparison.Ordinal )) { newPath += "."; } else { newPath += "\\."; } } #else if (path.EndsWith( m_directorySeparator + ".")) { if (newPath.EndsWith( m_directorySeparator)) { newPath += "."; } else { newPath += m_directorySeparator + "."; } } #endif // !FEATURE_PAL return newPath; } else return path; } } } // File provided for Reference Use Only by Microsoft Corporation (c) 2007. // ==++== // // Copyright (c) Microsoft Corporation. All rights reserved. // // ==--== // StringExpressionSet // namespace System.Security.Util { using System.Text; using System; using System.Collections; using System.Runtime.CompilerServices; using System.Globalization; using System.Runtime.Versioning; [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 ) { } 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); } public void AddExpressions( String str ) { if (str == null) throw new ArgumentNullException( "str" ); 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 !PLATFORM_UNIX if (!((temp.Length >= 3 && temp[1] == ':' && temp[2] == '\\' && ((temp[0] >= 'a' && temp[0] <= 'z') || (temp[0] >= 'A' && temp[0] <= 'Z'))) || (temp.Length >= 2 && temp[0] == '\\' && temp[1] == '\\'))) #else if(!(temp.Length >= 1 && temp[0] == m_directorySeparator)) #endif // !PLATFORM_UNIX { throw new ArgumentException( Environment.GetResourceString( "Argument_AbsolutePathRequired" ) ); } temp = CanonicalizePath( temp ); } m_list.Add( temp ); } } } Reduce(); } public void AddExpressions( String[] str, bool checkForDuplicates, bool needFullPath ) { AddExpressions(CreateListFromExpressions(str, needFullPath), checkForDuplicates); } public void AddExpressions( ArrayList exprArrayList, bool checkForDuplicates) { BCLDebug.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(); } internal static ArrayList CreateListFromExpressions(String[] str, bool needFullPath) { if (str == null) { throw new ArgumentNullException( "str" ); } 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 !PLATFORM_UNIX if (!((temp.Length >= 3 && temp[1] == ':' && temp[2] == '\\' && ((temp[0] >= 'a' && temp[0] <= 'z') || (temp[0] >= 'A' && temp[0] <= 'Z'))) || (temp.Length >= 2 && temp[0] == '\\' && temp[1] == '\\'))) #else if(!(temp.Length >= 1 && temp[0] == m_directorySeparator)) #endif // !PLATFORM_UNIX { throw new ArgumentException( Environment.GetResourceString( "Argument_AbsolutePathRequired" ) ); } temp = CanonicalizePath( temp, needFullPath ); retArrayList.Add( temp ); } } } return retArrayList; } protected void CheckList() { if (m_list == null && m_expressions != null) { CreateList(); } } protected String[] Split( String expressions ) { if (m_throwOnRelative) { ArrayList tempList = new ArrayList(); 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 ); } } 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 !PLATFORM_UNIX if (!((temp.Length >= 3 && temp[1] == ':' && temp[2] == '\\' && ((temp[0] >= 'a' && temp[0] <= 'z') || (temp[0] >= 'A' && temp[0] <= 'Z'))) || (temp.Length >= 2 && temp[0] == '\\' && temp[1] == '\\'))) #else if(!(temp.Length >= 1 && temp[0] == m_directorySeparator)) #endif // !PLATFORM_UNIX { 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; } } 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; } 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; } 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; } 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; } } 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 ); } 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++; } } } } [MethodImplAttribute(MethodImplOptions.InternalCall)] internal static extern String GetLongPathName( String path ); internal static String CanonicalizePath( String path ) { return CanonicalizePath( path, true ); } [ResourceExposure(ResourceScope.None)] // All internal, for string comparisons [ResourceConsumption(ResourceScope.Machine, ResourceScope.Machine)] internal static String CanonicalizePath( String path, bool needFullPath ) { #if !PLATFORM_UNIX if (path.IndexOf( '~' ) != -1) path = GetLongPathName( 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 !FEATURE_PAL if (path.EndsWith( "\\.", StringComparison.Ordinal )) { if (newPath.EndsWith( "\\", StringComparison.Ordinal )) { newPath += "."; } else { newPath += "\\."; } } #else if (path.EndsWith( m_directorySeparator + ".")) { if (newPath.EndsWith( m_directorySeparator)) { newPath += "."; } else { newPath += m_directorySeparator + "."; } } #endif // !FEATURE_PAL return newPath; } else return path; } } } // File provided for Reference Use Only by Microsoft Corporation (c) 2007.
Link Menu
This book is available now!
Buy at Amazon US or
Buy at Amazon UK
- GACMembershipCondition.cs
- DeviceContext2.cs
- MobileListItem.cs
- BaseCodePageEncoding.cs
- GridViewEditEventArgs.cs
- WriteTimeStream.cs
- CacheSection.cs
- ProcessHost.cs
- RightsManagementInformation.cs
- ContentValidator.cs
- CodeExpressionStatement.cs
- MgmtConfigurationRecord.cs
- SelectionGlyph.cs
- CornerRadius.cs
- ParserHooks.cs
- WorkflowViewStateService.cs
- TextContainerChangedEventArgs.cs
- Brush.cs
- sqlnorm.cs
- tibetanshape.cs
- DataRelation.cs
- TextView.cs
- XmlSchemaSimpleContentRestriction.cs
- ListDictionary.cs
- FileDialog_Vista_Interop.cs
- FixedTextSelectionProcessor.cs
- ListBoxItem.cs
- CopyOnWriteList.cs
- ServiceReference.cs
- OutputScope.cs
- MaskedTextBoxTextEditor.cs
- CharacterHit.cs
- LinearGradientBrush.cs
- Vector3DCollectionValueSerializer.cs
- XmlReaderSettings.cs
- ThreadPool.cs
- BitArray.cs
- PartialArray.cs
- EndpointInfo.cs
- ClientSession.cs
- MissingSatelliteAssemblyException.cs
- FullTextState.cs
- FixedLineResult.cs
- OperationResponse.cs
- DictionarySectionHandler.cs
- MSAAEventDispatcher.cs
- AncestorChangedEventArgs.cs
- ClientOptions.cs
- Marshal.cs
- FrameworkRichTextComposition.cs
- DbConnectionPoolGroup.cs
- WindowsTokenRoleProvider.cs
- DecimalAnimation.cs
- AuthenticatingEventArgs.cs
- DataGridViewColumnCollection.cs
- FontDriver.cs
- XmlQueryStaticData.cs
- FreezableDefaultValueFactory.cs
- PackageRelationship.cs
- TextDecorations.cs
- ScrollProperties.cs
- NotifyCollectionChangedEventArgs.cs
- NumericUpDownAccelerationCollection.cs
- Point3DValueSerializer.cs
- ToolStripDropDownClosingEventArgs.cs
- FocusManager.cs
- RegexCompilationInfo.cs
- Lock.cs
- AddInActivator.cs
- VisualStyleTypesAndProperties.cs
- AttachedPropertyBrowsableAttribute.cs
- SerializationInfoEnumerator.cs
- PriorityItem.cs
- RemotingSurrogateSelector.cs
- Deflater.cs
- PatternMatcher.cs
- AccessText.cs
- ContourSegment.cs
- QilDataSource.cs
- VirtualizedItemProviderWrapper.cs
- ConfigurationSectionCollection.cs
- TcpTransportSecurity.cs
- CLSCompliantAttribute.cs
- DataRecordInfo.cs
- NewArray.cs
- xdrvalidator.cs
- PasswordValidationException.cs
- EditorAttributeInfo.cs
- ExpressionNode.cs
- XmlFormatMapping.cs
- AssertUtility.cs
- TypeConvertions.cs
- X509SubjectKeyIdentifierClause.cs
- Animatable.cs
- DataGridHyperlinkColumn.cs
- DesignerActionService.cs
- ReadOnlyPropertyMetadata.cs
- TextInfo.cs
- SingleBodyParameterMessageFormatter.cs
- NGCUIElementCollectionSerializerAsync.cs