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
- WebPartConnectionsConnectVerb.cs
- TextBlock.cs
- MethodCallTranslator.cs
- XmlCountingReader.cs
- GridSplitter.cs
- LogicalChannel.cs
- OrderByBuilder.cs
- IncrementalHitTester.cs
- XPathDescendantIterator.cs
- SettingsSection.cs
- DetailsViewRowCollection.cs
- ValidationSummary.cs
- WebBrowserContainer.cs
- EntitySqlQueryCacheKey.cs
- TraceUtils.cs
- SpanIndex.cs
- AutoGeneratedFieldProperties.cs
- DataGridCommandEventArgs.cs
- DatePickerAutomationPeer.cs
- ThicknessAnimation.cs
- PeerTransportSecurityElement.cs
- ListGeneralPage.cs
- NativeMethods.cs
- Attachment.cs
- ReadContentAsBinaryHelper.cs
- InitiatorSessionSymmetricTransportSecurityProtocol.cs
- _LocalDataStore.cs
- ApplyTemplatesAction.cs
- AudioBase.cs
- ParamArrayAttribute.cs
- BatchStream.cs
- TimeoutValidationAttribute.cs
- CDSCollectionETWBCLProvider.cs
- CorruptingExceptionCommon.cs
- DefaultTypeArgumentAttribute.cs
- GPPOINTF.cs
- ValidationRuleCollection.cs
- DiagnosticSection.cs
- FrameworkElementFactory.cs
- SrgsRule.cs
- ResourceWriter.cs
- EditBehavior.cs
- TrustLevelCollection.cs
- ColumnResult.cs
- GatewayDefinition.cs
- ToolStripSeparatorRenderEventArgs.cs
- PreservationFileReader.cs
- StorageConditionPropertyMapping.cs
- ProxyAttribute.cs
- HtmlTitle.cs
- PagedControl.cs
- InkCanvasSelectionAdorner.cs
- DataChangedEventManager.cs
- Comparer.cs
- HttpConfigurationContext.cs
- TextProperties.cs
- DefaultWorkflowTransactionService.cs
- WorkflowOperationContext.cs
- GenericXmlSecurityToken.cs
- AvTraceFormat.cs
- XmlSchema.cs
- HyperLinkDataBindingHandler.cs
- DataGridViewColumn.cs
- NavigationService.cs
- TickBar.cs
- CollectionViewProxy.cs
- Serializer.cs
- CodeCompileUnit.cs
- MemberNameValidator.cs
- ClientTarget.cs
- CapabilitiesPattern.cs
- XPathDescendantIterator.cs
- XMLDiffLoader.cs
- RuntimeConfig.cs
- XhtmlCssHandler.cs
- DataShape.cs
- ProfileServiceManager.cs
- DbDataSourceEnumerator.cs
- XPathDocumentBuilder.cs
- AssociationEndMember.cs
- CodeTypeReferenceCollection.cs
- Control.cs
- PointUtil.cs
- Stream.cs
- CodeTypeReference.cs
- TextOutput.cs
- processwaithandle.cs
- BlockCollection.cs
- VisualStateChangedEventArgs.cs
- ComponentSerializationService.cs
- SmtpNetworkElement.cs
- WebColorConverter.cs
- ReliableOutputSessionChannel.cs
- StylusEditingBehavior.cs
- XmlSchemaImporter.cs
- XPathMultyIterator.cs
- Avt.cs
- PackWebRequest.cs
- RegexCaptureCollection.cs
- Table.cs