Code:
/ 4.0 / 4.0 / untmp / DEVDIV_TFS / Dev10 / Releases / RTMRel / ndp / clr / src / BCL / System / TypeNameParser.cs / 1305376 / TypeNameParser.cs
using System;
using System.Diagnostics.Contracts;
using System.IO;
using System.Reflection;
using System.Security;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading;
using System.Runtime.Versioning;
using Microsoft.Win32.SafeHandles;
#if !FEATURE_CORECLR
namespace System
{
[SecurityCritical]
internal class SafeTypeNameParserHandle : SafeHandleZeroOrMinusOneIsInvalid
{
#region QCalls
[SecurityCritical]
[ResourceExposure(ResourceScope.None)]
[DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode)]
[SuppressUnmanagedCodeSecurity]
private static extern void _ReleaseTypeNameParser(IntPtr pTypeNameParser);
#endregion
public SafeTypeNameParserHandle()
: base(true)
{
}
[SecurityCritical]
protected override bool ReleaseHandle()
{
_ReleaseTypeNameParser(handle);
handle = IntPtr.Zero;
return true;
}
}
internal sealed class TypeNameParser : IDisposable
{
#region QCalls
[SecurityCritical]
[ResourceExposure(ResourceScope.None)]
[DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode)]
[SuppressUnmanagedCodeSecurity]
private static extern void _CreateTypeNameParser(string typeName, ObjectHandleOnStack retHandle, bool throwOnError);
[SecurityCritical]
[ResourceExposure(ResourceScope.None)]
[DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode)]
[SuppressUnmanagedCodeSecurity]
private static extern void _GetNames(SafeTypeNameParserHandle pTypeNameParser, ObjectHandleOnStack retArray);
[SecurityCritical]
[ResourceExposure(ResourceScope.None)]
[DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode)]
[SuppressUnmanagedCodeSecurity]
private static extern void _GetTypeArguments(SafeTypeNameParserHandle pTypeNameParser, ObjectHandleOnStack retArray);
[SecurityCritical]
[ResourceExposure(ResourceScope.None)]
[DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode)]
[SuppressUnmanagedCodeSecurity]
private static extern void _GetModifiers(SafeTypeNameParserHandle pTypeNameParser, ObjectHandleOnStack retArray);
[SecurityCritical]
[ResourceExposure(ResourceScope.None)]
[DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode)]
[SuppressUnmanagedCodeSecurity]
private static extern void _GetAssemblyName(SafeTypeNameParserHandle pTypeNameParser, StringHandleOnStack retString);
#endregion
#region Static Members
[SecuritySafeCritical]
internal static Type GetType(
string typeName,
Func assemblyResolver,
Func typeResolver,
bool throwOnError,
bool ignoreCase,
ref StackCrawlMark stackMark)
{
if (typeName == null)
throw new ArgumentNullException("typeName");
if (typeName.Length > 0 && typeName[0] == '\0')
throw new ArgumentException(Environment.GetResourceString("Format_StringZeroLength"));
Contract.EndContractBlock();
Type ret = null;
SafeTypeNameParserHandle handle = CreateTypeNameParser(typeName, throwOnError);
if (handle != null)
{
// If we get here the typeName must have been successfully parsed.
// Let's construct the Type object.
using (TypeNameParser parser = new TypeNameParser(handle))
{
ret = parser.ConstructType(assemblyResolver, typeResolver, throwOnError, ignoreCase, ref stackMark);
}
}
return ret;
}
#endregion
#region Private Data Members
private SafeTypeNameParserHandle m_NativeParser;
private static readonly char[] SPECIAL_CHARS = {',', '[', ']', '&', '*', '+', '\\'}; /* see typeparse.h */
#endregion
#region Constructor and Disposer
[SecuritySafeCritical]
private TypeNameParser(SafeTypeNameParserHandle handle)
{
m_NativeParser = handle;
}
[SecuritySafeCritical]
public void Dispose()
{
m_NativeParser.Dispose();
}
#endregion
#region private Members
[SecuritySafeCritical]
private unsafe Type ConstructType(
Func assemblyResolver,
Func typeResolver,
bool throwOnError,
bool ignoreCase,
ref StackCrawlMark stackMark)
{
// assembly name
Assembly assembly = null;
string asmName = GetAssemblyName();
// GetAssemblyName never returns null
Contract.Assert(asmName != null);
if (asmName.Length > 0)
{
assembly = ResolveAssembly(asmName, assemblyResolver, throwOnError, ref stackMark);
if (assembly == null)
{
// Cannot resolve the assembly. If throwOnError is true we should have already thrown.
return null;
}
}
string[] names = GetNames();
if (names == null)
{
// This can only happen if the type name is an empty string or if the first char is '\0'
if (throwOnError)
throw new TypeLoadException(Environment.GetResourceString("Arg_TypeLoadNullStr"));
return null;
}
Type baseType = ResolveType(assembly, names, typeResolver, throwOnError, ignoreCase, ref stackMark);
if (baseType == null)
{
// Cannot resolve the type. If throwOnError is true we should have already thrown.
Contract.Assert(throwOnError == false);
return null;
}
SafeTypeNameParserHandle[] typeArguments = GetTypeArguments();
Type[] types = null;
if (typeArguments != null)
{
types = new Type[typeArguments.Length];
for (int i = 0; i < typeArguments.Length; i++)
{
Contract.Assert(typeArguments[i] != null);
using (TypeNameParser argParser = new TypeNameParser(typeArguments[i]))
{
types[i] = argParser.ConstructType(assemblyResolver, typeResolver, throwOnError, ignoreCase, ref stackMark);
}
if (types[i] == null)
{
// If throwOnError is true argParser.ConstructType should have already thrown.
Contract.Assert(throwOnError == false);
return null;
}
}
}
int[] modifiers = GetModifiers();
fixed (int* ptr = modifiers)
{
IntPtr intPtr = new IntPtr(ptr);
return RuntimeTypeHandle.GetTypeHelper(baseType, types, intPtr, modifiers == null ? 0 : modifiers.Length);
}
}
[SecuritySafeCritical]
private static Assembly ResolveAssembly(string asmName, Func assemblyResolver, bool throwOnError, ref StackCrawlMark stackMark)
{
Contract.Requires(asmName != null && asmName.Length > 0);
Assembly assembly = null;
if (assemblyResolver == null)
{
if (throwOnError)
{
assembly = RuntimeAssembly.InternalLoad(asmName, null, ref stackMark, false /*forIntrospection*/);
}
else
{
// When throwOnError is false we should only catch FileNotFoundException.
// Other exceptions like BadImangeFormatException should still fly.
try
{
assembly = RuntimeAssembly.InternalLoad(asmName, null, ref stackMark, false /*forIntrospection*/);
}
catch (FileNotFoundException)
{
return null;
}
}
}
else
{
assembly = assemblyResolver(new AssemblyName(asmName));
if (assembly == null && throwOnError)
{
throw new FileNotFoundException(Environment.GetResourceString("FileNotFound_ResolveAssembly", asmName));
}
}
return assembly;
}
private static Type ResolveType(Assembly assembly, string[] names, Func typeResolver, bool throwOnError, bool ignoreCase, ref StackCrawlMark stackMark)
{
Contract.Requires(names != null && names.Length > 0);
Type type = null;
// both the customer provided and the default type resolvers accept escaped type names
string OuterMostTypeName = EscapeTypeName(names[0]);
// Resolve the top level type.
if (typeResolver != null)
{
type = typeResolver(assembly, OuterMostTypeName, ignoreCase);
if (type == null && throwOnError)
{
string errorString = assembly == null ?
Environment.GetResourceString("TypeLoad_ResolveType", OuterMostTypeName) :
Environment.GetResourceString("TypeLoad_ResolveTypeFromAssembly", OuterMostTypeName, assembly.FullName);
throw new TypeLoadException(errorString);
}
}
else
{
if (assembly == null)
{
type = RuntimeType.GetType(OuterMostTypeName, throwOnError, ignoreCase, false, ref stackMark);
}
else
{
type = assembly.GetType(OuterMostTypeName, throwOnError, ignoreCase);
}
}
// Resolve nested types.
if (type != null)
{
BindingFlags bindingFlags = BindingFlags.NonPublic | BindingFlags.Public;
if (ignoreCase)
bindingFlags |= BindingFlags.IgnoreCase;
for (int i = 1; i < names.Length; i++)
{
type = type.GetNestedType(names[i], bindingFlags);
if (type == null)
{
if (throwOnError)
throw new TypeLoadException(Environment.GetResourceString("TypeLoad_ResolveNestedType", names[i], names[i-1]));
else
break;
}
}
}
return type;
}
private static string EscapeTypeName(string name)
{
if (name.IndexOfAny(SPECIAL_CHARS) < 0)
return name;
StringBuilder sb = new StringBuilder();
foreach (char c in name)
{
if (Array.IndexOf(SPECIAL_CHARS, c) >= 0)
sb.Append('\\');
sb.Append(c);
}
return sb.ToString();
}
[SecuritySafeCritical]
private static SafeTypeNameParserHandle CreateTypeNameParser(string typeName, bool throwOnError)
{
SafeTypeNameParserHandle retHandle = null;
_CreateTypeNameParser(typeName, JitHelpers.GetObjectHandleOnStack(ref retHandle), throwOnError);
return retHandle;
}
[SecuritySafeCritical]
private string[] GetNames()
{
string[] names = null;
_GetNames(m_NativeParser, JitHelpers.GetObjectHandleOnStack(ref names));
return names;
}
[SecuritySafeCritical]
private SafeTypeNameParserHandle[] GetTypeArguments()
{
SafeTypeNameParserHandle[] arguments = null;
_GetTypeArguments(m_NativeParser, JitHelpers.GetObjectHandleOnStack(ref arguments));
return arguments;
}
[SecuritySafeCritical]
private int[] GetModifiers()
{
int[] modifiers = null;
_GetModifiers(m_NativeParser, JitHelpers.GetObjectHandleOnStack(ref modifiers));
return modifiers;
}
[SecuritySafeCritical]
private string GetAssemblyName()
{
string assemblyName = null;
_GetAssemblyName(m_NativeParser, JitHelpers.GetStringHandleOnStack(ref assemblyName));
return assemblyName;
}
#endregion
}
}
#endif //!FEATURE_CORECLR
// 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
- EventSinkHelperWriter.cs
- RadialGradientBrush.cs
- ExtractorMetadata.cs
- EnvelopedSignatureTransform.cs
- XsdValidatingReader.cs
- SortExpressionBuilder.cs
- Lease.cs
- DrawingGroup.cs
- Baml6Assembly.cs
- DrawingContextWalker.cs
- StyleTypedPropertyAttribute.cs
- StrokeNodeEnumerator.cs
- SqlDataSource.cs
- CngAlgorithm.cs
- XhtmlStyleClass.cs
- SchemaImporter.cs
- ProxyWebPartManager.cs
- UrlAuthFailedErrorFormatter.cs
- Variable.cs
- StorageAssociationSetMapping.cs
- LassoHelper.cs
- PropertyItemInternal.cs
- GridViewUpdateEventArgs.cs
- OracleParameter.cs
- CollectionContainer.cs
- AppAction.cs
- SoapRpcServiceAttribute.cs
- localization.cs
- TraceSwitch.cs
- HandlerBase.cs
- XmlSchemaDatatype.cs
- RepeatBehavior.cs
- DocumentPaginator.cs
- AddInIpcChannel.cs
- ClientRuntimeConfig.cs
- dtdvalidator.cs
- OutputScopeManager.cs
- DateTimePickerDesigner.cs
- SessionStateModule.cs
- DetailsViewPageEventArgs.cs
- ExtendedTransformFactory.cs
- SymmetricAlgorithm.cs
- DataObjectCopyingEventArgs.cs
- IdentityHolder.cs
- NullableDecimalSumAggregationOperator.cs
- IntMinMaxAggregationOperator.cs
- ExceptionValidationRule.cs
- DataGridColumnReorderingEventArgs.cs
- DataExchangeServiceBinder.cs
- ReturnType.cs
- Constraint.cs
- XamlReader.cs
- TransactionManager.cs
- TextRunProperties.cs
- ValueUtilsSmi.cs
- BufferedStream2.cs
- AddValidationError.cs
- Dictionary.cs
- QueryOperatorEnumerator.cs
- UInt32Storage.cs
- DataGridViewSortCompareEventArgs.cs
- RawStylusInputReport.cs
- ProcessProtocolHandler.cs
- DataGridViewTopRowAccessibleObject.cs
- VirtualPath.cs
- SrgsToken.cs
- FlowDocumentPaginator.cs
- smtppermission.cs
- InvalidAsynchronousStateException.cs
- MeasureItemEvent.cs
- ScrollBar.cs
- ExpressionValueEditor.cs
- MetadataArtifactLoader.cs
- TransportContext.cs
- ModelFunctionTypeElement.cs
- StringCollectionEditor.cs
- CreateUserWizard.cs
- BinaryCommonClasses.cs
- AccessDataSourceView.cs
- DropShadowBitmapEffect.cs
- Attribute.cs
- TransformPattern.cs
- LiteralControl.cs
- Avt.cs
- StringPropertyBuilder.cs
- Int32Animation.cs
- InfiniteTimeSpanConverter.cs
- ControlType.cs
- PathGeometry.cs
- LoadedEvent.cs
- OrderedDictionary.cs
- ExceptionHandlers.cs
- SqlDataSourceFilteringEventArgs.cs
- FileLogRecordEnumerator.cs
- ErrorTableItemStyle.cs
- ComplexPropertyEntry.cs
- ApplicationActivator.cs
- NativeMethodsOther.cs
- Version.cs
- EdmProperty.cs