Code:
/ FXUpdate3074 / FXUpdate3074 / 1.1 / untmp / whidbey / QFE / ndp / clr / src / BCL / System / Security / Util / StringExpressionSet.cs / 4 / 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
//
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.
Link Menu

This book is available now!
Buy at Amazon US or
Buy at Amazon UK
- InstanceHandleReference.cs
- InvalidFilterCriteriaException.cs
- FontStretches.cs
- BezierSegment.cs
- LifetimeServices.cs
- ProtocolsSection.cs
- XmlAttributeCollection.cs
- Ops.cs
- XmlArrayItemAttribute.cs
- TextTreeRootTextBlock.cs
- DataStreamFromComStream.cs
- XsdDateTime.cs
- ExpressionBuilder.cs
- XamlTreeBuilder.cs
- Exceptions.cs
- SQLDoubleStorage.cs
- StoreContentChangedEventArgs.cs
- Attribute.cs
- XmlIgnoreAttribute.cs
- ToolStripOverflow.cs
- EastAsianLunisolarCalendar.cs
- NamedObjectList.cs
- DbConnectionInternal.cs
- DrawItemEvent.cs
- ReadOnlyHierarchicalDataSourceView.cs
- PlacementWorkspace.cs
- DocumentOrderQuery.cs
- DbParameterCollectionHelper.cs
- BaseTreeIterator.cs
- WizardSideBarListControlItemEventArgs.cs
- InstanceDataCollection.cs
- TextFormatterImp.cs
- ServiceDescription.cs
- _ProxyRegBlob.cs
- DataServiceExpressionVisitor.cs
- XmlTextReaderImplHelpers.cs
- MissingFieldException.cs
- SelectionRangeConverter.cs
- XamlToRtfParser.cs
- SqlTopReducer.cs
- PrincipalPermission.cs
- ToolStripPanel.cs
- XmlExceptionHelper.cs
- BigInt.cs
- DoubleCollection.cs
- ValidatorUtils.cs
- HttpResponse.cs
- RoutedCommand.cs
- ElementProxy.cs
- SafePointer.cs
- LinqDataSource.cs
- ExceptionAggregator.cs
- PostBackOptions.cs
- ISAPIRuntime.cs
- WebCodeGenerator.cs
- IDReferencePropertyAttribute.cs
- RtfNavigator.cs
- StrokeNode.cs
- Knowncolors.cs
- MinimizableAttributeTypeConverter.cs
- TextRunProperties.cs
- BevelBitmapEffect.cs
- CapabilitiesState.cs
- ChangeInterceptorAttribute.cs
- TreeViewHitTestInfo.cs
- sqlpipe.cs
- RelatedEnd.cs
- ConsoleKeyInfo.cs
- UnsafeNativeMethodsPenimc.cs
- TextPointer.cs
- Enum.cs
- NativeMethods.cs
- DataGridHeaderBorder.cs
- DbUpdateCommandTree.cs
- httpstaticobjectscollection.cs
- DelegateHelpers.Generated.cs
- XmlSerializerSection.cs
- mediaeventshelper.cs
- ProcessInfo.cs
- PageThemeCodeDomTreeGenerator.cs
- XamlGridLengthSerializer.cs
- TextDecorations.cs
- SessionParameter.cs
- ExpressionEvaluator.cs
- HtmlTableRowCollection.cs
- HtmlString.cs
- KnownTypes.cs
- UserInitiatedNavigationPermission.cs
- PrintPreviewDialog.cs
- BamlLocalizabilityResolver.cs
- XmlHierarchyData.cs
- ReachPrintTicketSerializer.cs
- SecurityState.cs
- WindowsFormsHost.cs
- ParseElement.cs
- connectionpool.cs
- ObjectRef.cs
- GB18030Encoding.cs
- Error.cs
- DecoratedNameAttribute.cs