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
- UnitControl.cs
- PartDesigner.cs
- Mouse.cs
- ProfileParameter.cs
- Emitter.cs
- StylusCaptureWithinProperty.cs
- SplitContainer.cs
- MappableObjectManager.cs
- SessionPageStatePersister.cs
- __ConsoleStream.cs
- CachedBitmap.cs
- XmlProcessingInstruction.cs
- MessageTraceRecord.cs
- BoolExpression.cs
- DataControlButton.cs
- ProviderSettingsCollection.cs
- DocumentsTrace.cs
- invalidudtexception.cs
- TimelineGroup.cs
- ClientConfigurationSystem.cs
- HTMLTextWriter.cs
- StylusCollection.cs
- CRYPTPROTECT_PROMPTSTRUCT.cs
- ErrorWebPart.cs
- AddressAccessDeniedException.cs
- Currency.cs
- ContractComponent.cs
- PartManifestEntry.cs
- SafeCertificateStore.cs
- CodeAttributeArgument.cs
- Pair.cs
- METAHEADER.cs
- WebPartZoneCollection.cs
- ResourcesBuildProvider.cs
- ConditionChanges.cs
- MethodResolver.cs
- columnmapkeybuilder.cs
- PackageFilter.cs
- AnyReturnReader.cs
- SystemSounds.cs
- IOException.cs
- validation.cs
- PrivacyNoticeBindingElementImporter.cs
- TextInfo.cs
- SourceSwitch.cs
- SqlCacheDependency.cs
- ArraySet.cs
- QilUnary.cs
- ColumnResizeUndoUnit.cs
- TreeViewItemAutomationPeer.cs
- Validator.cs
- StringUtil.cs
- SecurityRuntime.cs
- CaseKeyBox.ViewModel.cs
- SecurityTimestamp.cs
- SchemaTypeEmitter.cs
- InlinedAggregationOperatorEnumerator.cs
- DateTimeConverter2.cs
- BuildProviderCollection.cs
- XmlTextReader.cs
- WinFormsSpinner.cs
- HandlerWithFactory.cs
- IItemProperties.cs
- EntityKey.cs
- FlowLayoutPanelDesigner.cs
- ObjectListDesigner.cs
- DNS.cs
- VirtualizedContainerService.cs
- IisTraceListener.cs
- ResourcesBuildProvider.cs
- DbProviderServices.cs
- Activity.cs
- HttpRequestCacheValidator.cs
- MembershipSection.cs
- WebServiceMethodData.cs
- UnaryOperationBinder.cs
- Accessors.cs
- ByteConverter.cs
- ItemMap.cs
- CodeMemberEvent.cs
- SortKey.cs
- OdbcEnvironmentHandle.cs
- TableAutomationPeer.cs
- HotCommands.cs
- CodeIndexerExpression.cs
- FontStyle.cs
- CatalogZoneBase.cs
- FlowLayout.cs
- SafeHandles.cs
- ImageBrush.cs
- TableLayoutPanelCellPosition.cs
- QilDataSource.cs
- ReadOnlyDictionary.cs
- ThemeDictionaryExtension.cs
- WindowsAuthenticationModule.cs
- EntitySqlQueryCacheKey.cs
- WorkflowInstanceRecord.cs
- CopyNamespacesAction.cs
- ProfileSettingsCollection.cs
- ConfigXmlElement.cs