// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. using System; using System.Collections.Generic; using System.Reflection; using System.Runtime.CompilerServices; using Internal.Metadata.NativeFormat; using AssemblyFlags = Internal.Metadata.NativeFormat.AssemblyFlags; using Debug = System.Diagnostics.Debug; namespace System.Reflection.Runtime.General { [CLSCompliant(false)] public static partial class MetadataReaderExtensions { /// <summary> /// Convert raw token to a typed metadata handle. /// </summary> /// <param name="token">Token - raw integral handle representation</param> /// <returns>Token converted to handle</returns> public static unsafe Handle AsHandle(this int token) { return *(Handle*)&token; } /// <summary> /// Convert raw token to a typed metadata handle. /// </summary> /// <param name="token">Token - raw integral handle representation</param> /// <returns>Token converted to handle</returns> public static unsafe Handle AsHandle(this uint token) { return *(Handle*)&token; } /// <summary> /// Convert typed metadata handle to the raw token value. /// </summary> /// <param name="handle">Typed metadata handle</param> /// <returns>Token - raw integral handle represented as signed int</returns> public static unsafe int AsInt(this Handle handle) { return *(int*)&handle; } public static string GetString(this ConstantStringValueHandle handle, MetadataReader reader) { return reader.GetConstantStringValue(handle).Value; } // Useful for namespace Name string which can be a null handle. public static string GetStringOrNull(this ConstantStringValueHandle handle, MetadataReader reader) { if (handle.IsNil) return null; return reader.GetConstantStringValue(handle).Value; } public static bool IsTypeDefRefOrSpecHandle(this Handle handle, MetadataReader reader) { HandleType handleType = handle.HandleType; return handleType == HandleType.TypeDefinition || handleType == HandleType.TypeReference || handleType == HandleType.TypeSpecification; } public static bool IsTypeDefRefSpecOrModifiedTypeHandle(this Handle handle, MetadataReader reader) { HandleType handleType = handle.HandleType; return handleType == HandleType.TypeDefinition || handleType == HandleType.TypeReference || handleType == HandleType.TypeSpecification || handleType == HandleType.ModifiedType; } public static RuntimeAssemblyName ToRuntimeAssemblyName(this ScopeDefinitionHandle scopeDefinitionHandle, MetadataReader reader) { ScopeDefinition scopeDefinition = scopeDefinitionHandle.GetScopeDefinition(reader); return CreateRuntimeAssemblyNameFromMetadata( reader, scopeDefinition.Name, scopeDefinition.MajorVersion, scopeDefinition.MinorVersion, scopeDefinition.BuildNumber, scopeDefinition.RevisionNumber, scopeDefinition.Culture, scopeDefinition.PublicKey, scopeDefinition.Flags ); } public static RuntimeAssemblyName ToRuntimeAssemblyName(this ScopeReferenceHandle scopeReferenceHandle, MetadataReader reader) { ScopeReference scopeReference = scopeReferenceHandle.GetScopeReference(reader); return CreateRuntimeAssemblyNameFromMetadata( reader, scopeReference.Name, scopeReference.MajorVersion, scopeReference.MinorVersion, scopeReference.BuildNumber, scopeReference.RevisionNumber, scopeReference.Culture, scopeReference.PublicKeyOrToken, scopeReference.Flags ); } private static RuntimeAssemblyName CreateRuntimeAssemblyNameFromMetadata( MetadataReader reader, ConstantStringValueHandle name, ushort majorVersion, ushort minorVersion, ushort buildNumber, ushort revisionNumber, ConstantStringValueHandle culture, ByteCollection publicKeyOrToken, global::Internal.Metadata.NativeFormat.AssemblyFlags assemblyFlags) { AssemblyNameFlags assemblyNameFlags = (AssemblyNameFlags)(assemblyFlags & ( global::Internal.Metadata.NativeFormat.AssemblyFlags.PublicKey | global::Internal.Metadata.NativeFormat.AssemblyFlags.Retargetable | global::Internal.Metadata.NativeFormat.AssemblyFlags.ContentTypeMask)); ArrayBuilder<byte> keyOrTokenArrayBuilder = default; foreach (byte b in publicKeyOrToken) keyOrTokenArrayBuilder.Add(b); return new RuntimeAssemblyName( name.GetString(reader), new Version(majorVersion, minorVersion, buildNumber, revisionNumber), culture.GetStringOrNull(reader), assemblyNameFlags, keyOrTokenArrayBuilder.ToArray() ); } } } |