Code:
/ Dotnetfx_Win7_3.5.1 / Dotnetfx_Win7_3.5.1 / 3.5.1 / DEVDIV / depot / DevDiv / releases / whidbey / NetFXspW7 / ndp / clr / src / BCL / System / Reflection / CustomAttribute.cs / 1 / CustomAttribute.cs
// ==++==
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//
// ==--==
using System;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Collections;
using System.Collections.Generic;
using System.Resources;
using System.Diagnostics;
using System.Globalization;
using System.Security;
using System.Security.Permissions;
using System.Runtime.ConstrainedExecution;
namespace System.Reflection
{
[Serializable()]
[System.Runtime.InteropServices.ComVisible(true)]
public sealed class CustomAttributeData
{
#region Public Static Members
public static IList GetCustomAttributes(MemberInfo target)
{
if (target == null)
throw new ArgumentNullException("target");
IList cad = GetCustomAttributes(target.Module, target.MetadataToken);
int pcaCount = 0;
Attribute[] a = null;
if (target is RuntimeType)
a = PseudoCustomAttribute.GetCustomAttributes((RuntimeType)target, typeof(object), false, out pcaCount);
else if (target is RuntimeMethodInfo)
a = PseudoCustomAttribute.GetCustomAttributes((RuntimeMethodInfo)target, typeof(object), false, out pcaCount);
else if (target is RuntimeFieldInfo)
a = PseudoCustomAttribute.GetCustomAttributes((RuntimeFieldInfo)target, typeof(object), out pcaCount);
if (pcaCount == 0)
return cad;
CustomAttributeData[] pca = new CustomAttributeData[cad.Count + pcaCount];
cad.CopyTo(pca, pcaCount);
for (int i = 0; i < pcaCount; i++)
{
if (PseudoCustomAttribute.IsSecurityAttribute(a[i].GetType()))
continue;
pca[i] = new CustomAttributeData(a[i]);
}
return Array.AsReadOnly(pca);
}
public static IList GetCustomAttributes(Module target)
{
if (target == null)
throw new ArgumentNullException("target");
if (target.IsResourceInternal())
return new List();
return GetCustomAttributes(target, target.MetadataToken);
}
public static IList GetCustomAttributes(Assembly target)
{
if (target == null)
throw new ArgumentNullException("target");
return GetCustomAttributes(target.ManifestModule, target.AssemblyHandle.GetToken());
}
public static IList GetCustomAttributes(ParameterInfo target)
{
if (target == null)
throw new ArgumentNullException("target");
IList cad = GetCustomAttributes(target.Member.Module, target.MetadataToken);
int pcaCount = 0;
Attribute[] a = PseudoCustomAttribute.GetCustomAttributes((ParameterInfo)target, typeof(object), out pcaCount);
if (pcaCount == 0)
return cad;
CustomAttributeData[] pca = new CustomAttributeData[cad.Count + pcaCount];
cad.CopyTo(pca, pcaCount);
for (int i = 0; i < pcaCount; i++)
pca[i] = new CustomAttributeData(a[i]);
return Array.AsReadOnly(pca);
}
#endregion
#region Private Static Methods
private static CustomAttributeEncoding TypeToCustomAttributeEncoding(Type type)
{
if (type == typeof(int))
return CustomAttributeEncoding.Int32;
if (type.IsEnum)
return CustomAttributeEncoding.Enum;
if (type == typeof(string))
return CustomAttributeEncoding.String;
if (type == typeof(Type))
return CustomAttributeEncoding.Type;
if (type == typeof(object))
return CustomAttributeEncoding.Object;
if (type.IsArray)
return CustomAttributeEncoding.Array;
if (type == typeof(char))
return CustomAttributeEncoding.Char;
if (type == typeof(bool))
return CustomAttributeEncoding.Boolean;
if (type == typeof(byte))
return CustomAttributeEncoding.Byte;
if (type == typeof(sbyte))
return CustomAttributeEncoding.SByte;
if (type == typeof(short))
return CustomAttributeEncoding.Int16;
if (type == typeof(ushort))
return CustomAttributeEncoding.UInt16;
if (type == typeof(uint))
return CustomAttributeEncoding.UInt32;
if (type == typeof(long))
return CustomAttributeEncoding.Int64;
if (type == typeof(ulong))
return CustomAttributeEncoding.UInt64;
if (type == typeof(float))
return CustomAttributeEncoding.Float;
if (type == typeof(double))
return CustomAttributeEncoding.Double;
if (type.IsClass)
return CustomAttributeEncoding.Object;
if (type.IsInterface)
return CustomAttributeEncoding.Object;
if (type.IsValueType)
return CustomAttributeEncoding.Undefined;
throw new ArgumentException(Environment.GetResourceString("Argument_InvalidKindOfTypeForCA"), "type");
}
private static CustomAttributeType InitCustomAttributeType(Type parameterType, Module scope)
{
CustomAttributeEncoding encodedType = CustomAttributeData.TypeToCustomAttributeEncoding(parameterType);
CustomAttributeEncoding encodedArrayType = CustomAttributeEncoding.Undefined;
CustomAttributeEncoding encodedEnumType = CustomAttributeEncoding.Undefined;
string enumName = null;
if (encodedType == CustomAttributeEncoding.Array)
{
parameterType = parameterType.GetElementType();
encodedArrayType = CustomAttributeData.TypeToCustomAttributeEncoding(parameterType);
}
if (encodedType == CustomAttributeEncoding.Enum || encodedArrayType == CustomAttributeEncoding.Enum)
{
encodedEnumType = TypeToCustomAttributeEncoding(Enum.GetUnderlyingType(parameterType));
if (parameterType.Module == scope)
enumName = parameterType.FullName;
else
enumName = parameterType.AssemblyQualifiedName;
}
return new CustomAttributeType(encodedType, encodedArrayType, encodedEnumType, enumName);
}
private static IList GetCustomAttributes(Module module, int tkTarget)
{
CustomAttributeRecord[] records = GetCustomAttributeRecords(module, tkTarget);
CustomAttributeData[] customAttributes = new CustomAttributeData[records.Length];
for (int i = 0; i < records.Length; i++)
customAttributes[i] = new CustomAttributeData(module, records[i]);
return Array.AsReadOnly(customAttributes);
}
#endregion
#region Internal Static Members
internal unsafe static CustomAttributeRecord[] GetCustomAttributeRecords(Module module, int targetToken)
{
MetadataImport scope = module.MetadataImport;
int cCustomAttributeTokens = scope.EnumCustomAttributesCount(targetToken);
int* tkCustomAttributeTokens = stackalloc int[cCustomAttributeTokens];
scope.EnumCustomAttributes(targetToken, tkCustomAttributeTokens, cCustomAttributeTokens);
CustomAttributeRecord[] records = new CustomAttributeRecord[cCustomAttributeTokens];
for (int i = 0; i < cCustomAttributeTokens; i++)
{
scope.GetCustomAttributeProps(
tkCustomAttributeTokens[i], out records[i].tkCtor.Value, out records[i].blob);
}
return records;
}
internal static CustomAttributeTypedArgument Filter(IList attrs, Type caType, string name)
{
for (int i = 0; i < attrs.Count; i++)
{
if (attrs[i].Constructor.DeclaringType == caType)
{
IList namedArguments = attrs[i].NamedArguments;
for (int j = 0; j < namedArguments.Count; j++)
{
if (namedArguments[j].MemberInfo.Name.Equals(name))
return namedArguments[j].TypedValue;
}
}
}
return new CustomAttributeTypedArgument();
}
internal static CustomAttributeTypedArgument Filter(IList attrs, Type caType, int parameter)
{
for (int i = 0; i < attrs.Count; i++)
{
if (attrs[i].Constructor.DeclaringType == caType)
{
return attrs[i].ConstructorArguments[parameter];
}
}
return new CustomAttributeTypedArgument();
}
#endregion
#region Private Data Members
private ConstructorInfo m_ctor;
private Module m_scope;
private MemberInfo[] m_members;
private CustomAttributeCtorParameter[] m_ctorParams;
private CustomAttributeNamedParameter[] m_namedParams;
private IList m_typedCtorArgs;
private IList m_namedArgs;
#endregion
#region Constructor
internal CustomAttributeData(Module scope, CustomAttributeRecord caRecord)
{
m_scope = scope;
m_ctor = (ConstructorInfo)RuntimeType.GetMethodBase(scope, caRecord.tkCtor);
ParameterInfo[] parameters = m_ctor.GetParametersNoCopy();
m_ctorParams = new CustomAttributeCtorParameter[parameters.Length];
for (int i = 0; i < parameters.Length; i++)
m_ctorParams[i] = new CustomAttributeCtorParameter(InitCustomAttributeType(parameters[i].ParameterType, scope));
FieldInfo[] fields = m_ctor.DeclaringType.GetFields(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
PropertyInfo[] properties = m_ctor.DeclaringType.GetProperties(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
m_namedParams = new CustomAttributeNamedParameter[properties.Length + fields.Length];
for (int i = 0; i < fields.Length; i++)
m_namedParams[i] = new CustomAttributeNamedParameter(
fields[i].Name, CustomAttributeEncoding.Field, InitCustomAttributeType(fields[i].FieldType, scope));
for (int i = 0; i < properties.Length; i++)
m_namedParams[i + fields.Length] = new CustomAttributeNamedParameter(
properties[i].Name, CustomAttributeEncoding.Property, InitCustomAttributeType(properties[i].PropertyType, scope));
m_members = new MemberInfo[fields.Length + properties.Length];
fields.CopyTo(m_members, 0);
properties.CopyTo(m_members, fields.Length);
CustomAttributeEncodedArgument.ParseAttributeArguments(caRecord.blob, ref m_ctorParams, ref m_namedParams, m_scope);
}
#endregion
#region Pseudo Custom Attribute Constructor
internal CustomAttributeData(Attribute attribute)
{
if (attribute is DllImportAttribute)
Init((DllImportAttribute)attribute);
else if (attribute is FieldOffsetAttribute)
Init((FieldOffsetAttribute)attribute);
else if (attribute is MarshalAsAttribute)
Init((MarshalAsAttribute)attribute);
else
Init(attribute);
}
private void Init(DllImportAttribute dllImport)
{
Type type = typeof(DllImportAttribute);
m_ctor = type.GetConstructors(BindingFlags.Public | BindingFlags.Instance)[0];
m_typedCtorArgs = Array.AsReadOnly(new CustomAttributeTypedArgument[]
{
new CustomAttributeTypedArgument(dllImport.Value),
});
m_namedArgs = Array.AsReadOnly(new CustomAttributeNamedArgument[]
{
new CustomAttributeNamedArgument(type.GetField("EntryPoint"), dllImport.EntryPoint),
new CustomAttributeNamedArgument(type.GetField("CharSet"), dllImport.CharSet),
new CustomAttributeNamedArgument(type.GetField("ExactSpelling"), dllImport.ExactSpelling),
new CustomAttributeNamedArgument(type.GetField("SetLastError"), dllImport.SetLastError),
new CustomAttributeNamedArgument(type.GetField("PreserveSig"), dllImport.PreserveSig),
new CustomAttributeNamedArgument(type.GetField("CallingConvention"), dllImport.CallingConvention),
new CustomAttributeNamedArgument(type.GetField("BestFitMapping"), dllImport.BestFitMapping),
new CustomAttributeNamedArgument(type.GetField("ThrowOnUnmappableChar"), dllImport.ThrowOnUnmappableChar)
});
}
private void Init(FieldOffsetAttribute fieldOffset)
{
m_ctor = typeof(FieldOffsetAttribute).GetConstructors(BindingFlags.Public | BindingFlags.Instance)[0];
m_typedCtorArgs = Array.AsReadOnly(new CustomAttributeTypedArgument[] {
new CustomAttributeTypedArgument(fieldOffset.Value)
});
m_namedArgs = Array.AsReadOnly(new CustomAttributeNamedArgument[0]);
}
private void Init(MarshalAsAttribute marshalAs)
{
Type type = typeof(MarshalAsAttribute);
m_ctor = type.GetConstructors(BindingFlags.Public | BindingFlags.Instance)[0];
m_typedCtorArgs = Array.AsReadOnly(new CustomAttributeTypedArgument[]
{
new CustomAttributeTypedArgument(marshalAs.Value),
});
int i = 3; // ArraySubType, SizeParamIndex, SizeConst
if (marshalAs.MarshalType != null) i++;
if (marshalAs.MarshalTypeRef != null) i++;
if (marshalAs.MarshalCookie != null) i++;
#if FEATURE_COMINTEROP
i++; // IidParameterIndex
i++; // SafeArraySubType
if (marshalAs.SafeArrayUserDefinedSubType != null) i++;
#endif // FEATURE_COMINTEROP
CustomAttributeNamedArgument[] namedArgs = new CustomAttributeNamedArgument[i];
i = 0;
namedArgs[i++] = new CustomAttributeNamedArgument(type.GetField("ArraySubType"), marshalAs.ArraySubType);
namedArgs[i++] = new CustomAttributeNamedArgument(type.GetField("SizeParamIndex"), marshalAs.SizeParamIndex);
namedArgs[i++] = new CustomAttributeNamedArgument(type.GetField("SizeConst"), marshalAs.SizeConst);
#if FEATURE_COMINTEROP
namedArgs[i++] = new CustomAttributeNamedArgument(type.GetField("IidParameterIndex"), marshalAs.IidParameterIndex);
namedArgs[i++] = new CustomAttributeNamedArgument(type.GetField("SafeArraySubType"), marshalAs.SafeArraySubType);
#endif // FEATURE_COMINTEROP
if (marshalAs.MarshalType != null)
namedArgs[i++] = new CustomAttributeNamedArgument(type.GetField("MarshalType"), marshalAs.MarshalType);
if (marshalAs.MarshalTypeRef != null)
namedArgs[i++] = new CustomAttributeNamedArgument(type.GetField("MarshalTypeRef"), marshalAs.MarshalTypeRef);
if (marshalAs.MarshalCookie != null)
namedArgs[i++] = new CustomAttributeNamedArgument(type.GetField("MarshalCookie"), marshalAs.MarshalCookie);
#if FEATURE_COMINTEROP
if (marshalAs.SafeArrayUserDefinedSubType != null)
namedArgs[i++] = new CustomAttributeNamedArgument(type.GetField("SafeArrayUserDefinedSubType"), marshalAs.SafeArrayUserDefinedSubType);
#endif // FEATURE_COMINTEROP
m_namedArgs = Array.AsReadOnly(namedArgs);
}
private void Init(object pca)
{
m_ctor = pca.GetType().GetConstructors(BindingFlags.Public | BindingFlags.Instance)[0];
m_typedCtorArgs = Array.AsReadOnly(new CustomAttributeTypedArgument[0]);
m_namedArgs = Array.AsReadOnly(new CustomAttributeNamedArgument[0]);
}
#endregion
#region Object Override
public override string ToString()
{
string ctorArgs = "";
for (int i = 0; i < ConstructorArguments.Count; i ++)
ctorArgs += String.Format(CultureInfo.CurrentCulture, i == 0 ? "{0}" : ", {0}", ConstructorArguments[i]);
string namedArgs = "";
for (int i = 0; i < NamedArguments.Count; i ++)
namedArgs += String.Format(CultureInfo.CurrentCulture, i == 0 && ctorArgs.Length == 0 ? "{0}" : ", {0}", NamedArguments[i]);
return String.Format(CultureInfo.CurrentCulture, "[{0}({1}{2})]", Constructor.DeclaringType.FullName, ctorArgs, namedArgs);
}
public override int GetHashCode()
{
return base.GetHashCode();
}
public override bool Equals(object obj)
{
return obj == (object)this;
}
#endregion
#region Public Members
[System.Runtime.InteropServices.ComVisible(true)]
public ConstructorInfo Constructor { get { return m_ctor; } }
[System.Runtime.InteropServices.ComVisible(true)]
public IList ConstructorArguments
{
get
{
if (m_typedCtorArgs == null)
{
CustomAttributeTypedArgument[] typedCtorArgs = new CustomAttributeTypedArgument[m_ctorParams.Length];
for (int i = 0; i < typedCtorArgs.Length; i++)
{
CustomAttributeEncodedArgument encodedArg = m_ctorParams[i].CustomAttributeEncodedArgument;
typedCtorArgs[i] = new CustomAttributeTypedArgument(m_scope, m_ctorParams[i].CustomAttributeEncodedArgument);
}
m_typedCtorArgs = Array.AsReadOnly(typedCtorArgs);
}
return m_typedCtorArgs;
}
}
public IList NamedArguments
{
get
{
if (m_namedArgs == null)
{
if (m_namedParams == null)
return null;
int cNamedArgs = 0;
for (int i = 0; i < m_namedParams.Length; i ++)
{
if (m_namedParams[i].EncodedArgument.CustomAttributeType.EncodedType != CustomAttributeEncoding.Undefined)
cNamedArgs++;
}
CustomAttributeNamedArgument[] namedArgs = new CustomAttributeNamedArgument[cNamedArgs];
for (int i = 0, j = 0; i < m_namedParams.Length; i++)
{
if (m_namedParams[i].EncodedArgument.CustomAttributeType.EncodedType != CustomAttributeEncoding.Undefined)
namedArgs[j++] = new CustomAttributeNamedArgument(
m_members[i], new CustomAttributeTypedArgument(m_scope, m_namedParams[i].EncodedArgument));
}
m_namedArgs = Array.AsReadOnly(namedArgs);
}
return m_namedArgs;
}
}
#endregion
}
[Serializable()]
[System.Runtime.InteropServices.ComVisible(true)]
public struct CustomAttributeNamedArgument
{
#region Public Static Members
public static bool operator ==(CustomAttributeNamedArgument left, CustomAttributeNamedArgument right)
{
return left.Equals(right);
}
public static bool operator !=(CustomAttributeNamedArgument left, CustomAttributeNamedArgument right)
{
return !left.Equals(right);
}
#endregion
#region Private Data Members
private MemberInfo m_memberInfo;
private CustomAttributeTypedArgument m_value;
#endregion
#region Constructor
internal CustomAttributeNamedArgument(MemberInfo memberInfo, object value)
{
m_memberInfo = memberInfo;
m_value = new CustomAttributeTypedArgument(value);
}
internal CustomAttributeNamedArgument(MemberInfo memberInfo, CustomAttributeTypedArgument value)
{
m_memberInfo = memberInfo;
m_value = value;
}
#endregion
#region Object Override
public override string ToString()
{
return String.Format(CultureInfo.CurrentCulture, "{0} = {1}", MemberInfo.Name, TypedValue.ToString(ArgumentType != typeof(object)));
}
public override int GetHashCode()
{
return base.GetHashCode();
}
public override bool Equals(object obj)
{
return obj == (object)this;
}
#endregion
#region Internal Members
internal Type ArgumentType
{
get
{
return m_memberInfo is FieldInfo ?
((FieldInfo)m_memberInfo).FieldType :
((PropertyInfo)m_memberInfo).PropertyType;
}
}
#endregion
#region Public Members
public MemberInfo MemberInfo { get { return m_memberInfo; } }
public CustomAttributeTypedArgument TypedValue { get { return m_value; } }
#endregion
}
[Serializable()]
[ComVisible(true)]
public struct CustomAttributeTypedArgument
{
#region Public Static Members
public static bool operator ==(CustomAttributeTypedArgument left, CustomAttributeTypedArgument right)
{
return left.Equals(right);
}
public static bool operator !=(CustomAttributeTypedArgument left, CustomAttributeTypedArgument right)
{
return !left.Equals(right);
}
#endregion
#region Private Static Methods
private static Type CustomAttributeEncodingToType(CustomAttributeEncoding encodedType)
{
switch (encodedType)
{
case (CustomAttributeEncoding.Enum):
return typeof(Enum);
case (CustomAttributeEncoding.Int32):
return typeof(int);
case (CustomAttributeEncoding.String):
return typeof(string);
case (CustomAttributeEncoding.Type):
return typeof(Type);
case (CustomAttributeEncoding.Array):
return typeof(Array);
case (CustomAttributeEncoding.Char):
return typeof(char);
case (CustomAttributeEncoding.Boolean):
return typeof(bool);
case (CustomAttributeEncoding.SByte):
return typeof(sbyte);
case (CustomAttributeEncoding.Byte):
return typeof(byte);
case (CustomAttributeEncoding.Int16):
return typeof(short);
case (CustomAttributeEncoding.UInt16):
return typeof(ushort);
case (CustomAttributeEncoding.UInt32):
return typeof(uint);
case (CustomAttributeEncoding.Int64):
return typeof(long);
case (CustomAttributeEncoding.UInt64):
return typeof(ulong);
case (CustomAttributeEncoding.Float):
return typeof(float);
case (CustomAttributeEncoding.Double):
return typeof(double);
case (CustomAttributeEncoding.Object):
return typeof(object);
default :
throw new ArgumentException(Environment.GetResourceString("Arg_EnumIllegalVal", (int)encodedType), "encodedType");
}
}
private static object EncodedValueToRawValue(long val, CustomAttributeEncoding encodedType)
{
switch (encodedType)
{
case CustomAttributeEncoding.Boolean:
return (byte)val != 0;
case CustomAttributeEncoding.Char:
return (char)val;
case CustomAttributeEncoding.Byte:
return (byte)val;
case CustomAttributeEncoding.SByte:
return (sbyte)val;
case CustomAttributeEncoding.Int16:
return (short)val;
case CustomAttributeEncoding.UInt16:
return (ushort)val;
case CustomAttributeEncoding.Int32:
return (int)val;
case CustomAttributeEncoding.UInt32:
return (uint)val;
case CustomAttributeEncoding.Int64:
return (long)val;
case CustomAttributeEncoding.UInt64:
return (ulong)val;
case CustomAttributeEncoding.Float:
unsafe { return *(float*)&val; }
case CustomAttributeEncoding.Double:
unsafe { return *(double*)&val; }
default:
throw new ArgumentException(Environment.GetResourceString("Arg_EnumIllegalVal", (int)val), "val");
}
}
private static Type ResolveType(Module scope, string typeName)
{
Type type = RuntimeTypeHandle.GetTypeByNameUsingCARules(typeName, scope);
if (type == null)
throw new InvalidOperationException(
String.Format(CultureInfo.CurrentUICulture, Environment.GetResourceString("Arg_CATypeResolutionFailed"), typeName));
return type;
}
#endregion
#region Private Data Members
private object m_value;
private Type m_argumentType;
#endregion
#region Constructor
internal CustomAttributeTypedArgument(object value)
{
m_argumentType = value.GetType();
if (m_argumentType.IsEnum)
{
if (Enum.GetUnderlyingType(m_argumentType) == typeof(int))
m_value = (int)value;
else if (Enum.GetUnderlyingType(m_argumentType) == typeof(short))
m_value = (short)value;
else
throw new ArgumentException(Environment.GetResourceString("Argument_EnumIsNotIntOrShort"), "value");
}
else
{
m_value = value;
}
}
internal CustomAttributeTypedArgument(Module scope, CustomAttributeEncodedArgument encodedArg)
{
CustomAttributeEncoding encodedType = encodedArg.CustomAttributeType.EncodedType;
if (encodedType == CustomAttributeEncoding.Undefined)
throw new ArgumentException("encodedArg");
else if (encodedType == CustomAttributeEncoding.Enum)
{
m_argumentType = ResolveType(scope, encodedArg.CustomAttributeType.EnumName);
m_value = EncodedValueToRawValue(encodedArg.PrimitiveValue, encodedArg.CustomAttributeType.EncodedEnumType);
}
else if (encodedType == CustomAttributeEncoding.String)
{
m_argumentType = typeof(string);
m_value = encodedArg.StringValue;
}
else if (encodedType == CustomAttributeEncoding.Type)
{
m_argumentType = typeof(Type);
m_value = null;
if (encodedArg.StringValue != null)
m_value = ResolveType(scope, encodedArg.StringValue);
}
else if (encodedType == CustomAttributeEncoding.Array)
{
encodedType = encodedArg.CustomAttributeType.EncodedArrayType;
Type elementType;
if (encodedType == CustomAttributeEncoding.Enum)
{
elementType = ResolveType(scope, encodedArg.CustomAttributeType.EnumName);
}
else
{
elementType = CustomAttributeEncodingToType(encodedType);
}
m_argumentType = elementType.MakeArrayType();
if (encodedArg.ArrayValue == null)
{
m_value = null;
}
else
{
CustomAttributeTypedArgument[] arrayValue = new CustomAttributeTypedArgument[encodedArg.ArrayValue.Length];
for (int i = 0; i < arrayValue.Length; i++)
arrayValue[i] = new CustomAttributeTypedArgument(scope, encodedArg.ArrayValue[i]);
m_value = Array.AsReadOnly(arrayValue);
}
}
else
{
m_argumentType = CustomAttributeEncodingToType(encodedType);
m_value = EncodedValueToRawValue(encodedArg.PrimitiveValue, encodedType);
}
}
#endregion
#region Object Overrides
public override string ToString() { return ToString(false); }
internal string ToString(bool typed)
{
if (ArgumentType.IsEnum)
return String.Format(CultureInfo.CurrentCulture, typed ? "{0}" : "({1}){0}", Value, ArgumentType.FullName);
else if (Value == null)
return String.Format(CultureInfo.CurrentCulture, typed ? "null" : "({0})null", ArgumentType.Name);
else if (ArgumentType == typeof(string))
return String.Format(CultureInfo.CurrentCulture, "\"{0}\"", Value);
else if (ArgumentType == typeof(char))
return String.Format(CultureInfo.CurrentCulture, "'{0}'", Value);
else if (ArgumentType == typeof(Type))
return String.Format(CultureInfo.CurrentCulture, "typeof({0})", ((Type)Value).FullName);
else if (ArgumentType.IsArray)
{
string result = null;
IList array = Value as IList;
Type elementType = ArgumentType.GetElementType();
result = String.Format(CultureInfo.CurrentCulture, @"new {0}[{1}] {{ ", elementType.IsEnum ? elementType.FullName : elementType.Name, array.Count);
for (int i = 0; i < array.Count; i++)
result += String.Format(CultureInfo.CurrentCulture, i == 0 ? "{0}" : ", {0}", array[i].ToString(elementType != typeof(object)));
return result += " }";
}
return String.Format(CultureInfo.CurrentCulture, typed ? "{0}" : "({1}){0}", Value, ArgumentType.Name);
}
public override int GetHashCode()
{
return base.GetHashCode();
}
public override bool Equals(object obj)
{
return obj == (object)this;
}
#endregion
#region Public Members
public Type ArgumentType
{
get
{
return m_argumentType;
}
}
public object Value
{
get
{
return m_value;
}
}
#endregion
}
[Serializable()]
internal struct CustomAttributeRecord
{
internal ConstArray blob;
internal MetadataToken tkCtor;
}
[Serializable()]
internal enum CustomAttributeEncoding : int
{
Undefined = 0,
Boolean = CorElementType.Boolean,
Char = CorElementType.Char,
SByte = CorElementType.I1,
Byte = CorElementType.U1,
Int16 = CorElementType.I2,
UInt16 = CorElementType.U2,
Int32 = CorElementType.I4,
UInt32 = CorElementType.U4,
Int64 = CorElementType.I8,
UInt64 = CorElementType.U8,
Float = CorElementType.R4,
Double = CorElementType.R8,
String = CorElementType.String,
Array = CorElementType.SzArray,
Type = 0x50,
Object = 0x51,
Field = 0x53,
Property = 0x54,
Enum = 0x55
}
[Serializable()]
[StructLayout(LayoutKind.Auto)]
internal struct CustomAttributeEncodedArgument
{
#region Parser
[MethodImplAttribute(MethodImplOptions.InternalCall)]
private static extern void ParseAttributeArguments(
IntPtr pCa,
int cCa,
ref CustomAttributeCtorParameter[] CustomAttributeCtorParameters,
ref CustomAttributeNamedParameter[] CustomAttributeTypedArgument,
IntPtr assembly);
internal static void ParseAttributeArguments(ConstArray attributeBlob,
ref CustomAttributeCtorParameter[] customAttributeCtorParameters,
ref CustomAttributeNamedParameter[] customAttributeNamedParameters,
Module customAttributeModule)
{
if (customAttributeModule == null)
throw new ArgumentNullException("customAttributeModule");
if (customAttributeNamedParameters == null)
customAttributeNamedParameters = new CustomAttributeNamedParameter[0];
CustomAttributeCtorParameter[] _customAttributeCtorParameters = customAttributeCtorParameters;
CustomAttributeNamedParameter[] _customAttributeNamedParameters = customAttributeNamedParameters;
unsafe
{
ParseAttributeArguments(
attributeBlob.Signature,
(int)attributeBlob.Length,
ref _customAttributeCtorParameters,
ref _customAttributeNamedParameters,
(IntPtr)customAttributeModule.Assembly.AssemblyHandle.Value);
}
customAttributeCtorParameters = _customAttributeCtorParameters;
customAttributeNamedParameters = _customAttributeNamedParameters;
}
#endregion
#region Private Data Members
private long m_primitiveValue;
private CustomAttributeEncodedArgument[] m_arrayValue;
private string m_stringValue;
private CustomAttributeType m_type;
#endregion
#region Public Members
public CustomAttributeType CustomAttributeType { get { return m_type; } }
public long PrimitiveValue { get { return m_primitiveValue; } }
public CustomAttributeEncodedArgument[] ArrayValue { get { return m_arrayValue; } }
public string StringValue { get { return m_stringValue; } }
#endregion
}
[Serializable()]
[StructLayout(LayoutKind.Auto)]
internal struct CustomAttributeNamedParameter
{
#region Private Data Members
private string m_argumentName;
private CustomAttributeEncoding m_fieldOrProperty;
private CustomAttributeEncoding m_padding;
private CustomAttributeType m_type;
private CustomAttributeEncodedArgument m_encodedArgument;
#endregion
#region Constructor
public CustomAttributeNamedParameter(string argumentName, CustomAttributeEncoding fieldOrProperty, CustomAttributeType type)
{
if (argumentName == null)
throw new ArgumentNullException("argumentName");
m_argumentName = argumentName;
m_fieldOrProperty = fieldOrProperty;
m_padding = fieldOrProperty;
m_type = type;
m_encodedArgument = new CustomAttributeEncodedArgument();
}
#endregion
#region Public Members
public CustomAttributeEncodedArgument EncodedArgument { get { return m_encodedArgument; } }
#endregion
}
[Serializable()]
[StructLayout(LayoutKind.Auto)]
internal struct CustomAttributeCtorParameter
{
#region Private Data Members
private CustomAttributeType m_type;
private CustomAttributeEncodedArgument m_encodedArgument;
#endregion
#region Constructor
public CustomAttributeCtorParameter(CustomAttributeType type)
{
m_type = type;
m_encodedArgument = new CustomAttributeEncodedArgument();
}
#endregion
#region Public Members
public CustomAttributeEncodedArgument CustomAttributeEncodedArgument { get { return m_encodedArgument; } }
#endregion
}
// Note: This is a managed representation of a frame type defined in vm\frames.h; please ensure the layout remains
// synchronized.
[StructLayout(LayoutKind.Sequential)]
internal struct SecurityContextFrame
{
IntPtr m_GSCookie; // This is actually at a negative offset in the real frame definition
IntPtr __VFN_table; // This is the real start of the SecurityContextFrame
IntPtr m_Next;
IntPtr m_Assembly;
[MethodImplAttribute(MethodImplOptions.InternalCall)]
public extern void Push(Assembly assembly);
[MethodImplAttribute(MethodImplOptions.InternalCall)]
[ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]
public extern void Pop();
}
[Serializable()]
[StructLayout(LayoutKind.Auto)]
internal struct CustomAttributeType
{
#region Private Data Members
/// The most complicated type is an enum[] in which case...
private string m_enumName; // ...enum name
private CustomAttributeEncoding m_encodedType; // ...array
private CustomAttributeEncoding m_encodedEnumType; // ...enum
private CustomAttributeEncoding m_encodedArrayType; // ...enum type
private CustomAttributeEncoding m_padding;
#endregion
#region Constructor
public CustomAttributeType(CustomAttributeEncoding encodedType, CustomAttributeEncoding encodedArrayType,
CustomAttributeEncoding encodedEnumType, string enumName)
{
m_encodedType = encodedType;
m_encodedArrayType = encodedArrayType;
m_encodedEnumType = encodedEnumType;
m_enumName = enumName;
m_padding = m_encodedType;
}
#endregion
#region Public Members
public CustomAttributeEncoding EncodedType { get { return m_encodedType; } }
public CustomAttributeEncoding EncodedEnumType { get { return m_encodedEnumType; } }
public CustomAttributeEncoding EncodedArrayType { get { return m_encodedArrayType; } }
[System.Runtime.InteropServices.ComVisible(true)]
public string EnumName { get { return m_enumName; } }
#endregion
}
internal unsafe static class CustomAttribute
{
#region Internal Static Members
internal static bool IsDefined(RuntimeType type, RuntimeType caType, bool inherit)
{
ASSERT.PRECONDITION(type != null);
if (type.GetElementType() != null)
return false;
if (PseudoCustomAttribute.IsDefined(type, caType))
return true;
if (IsCustomAttributeDefined(type.Module, type.MetadataToken, caType))
return true;
if (!inherit)
return false;
type = type.BaseType as RuntimeType;
while (type != null)
{
if (IsCustomAttributeDefined(type.Module, type.MetadataToken, caType, inherit))
return true;
type = type.BaseType as RuntimeType;
}
return false;
}
internal static bool IsDefined(RuntimeMethodInfo method, RuntimeType caType, bool inherit)
{
ASSERT.PRECONDITION(method != null);
if (PseudoCustomAttribute.IsDefined(method, caType))
return true;
if (IsCustomAttributeDefined(method.Module, method.MetadataToken, caType))
return true;
if (!inherit)
return false;
method = method.GetParentDefinition() as RuntimeMethodInfo;
while (method != null)
{
if (IsCustomAttributeDefined(method.Module, method.MetadataToken, caType, inherit))
return true;
method = method.GetParentDefinition() as RuntimeMethodInfo;
}
return false;
}
internal static bool IsDefined(RuntimeConstructorInfo ctor, RuntimeType caType)
{
ASSERT.PRECONDITION(ctor != null);
if (PseudoCustomAttribute.IsDefined(ctor, caType))
return true;
return IsCustomAttributeDefined(ctor.Module, ctor.MetadataToken, caType);
}
internal static bool IsDefined(RuntimePropertyInfo property, RuntimeType caType)
{
ASSERT.PRECONDITION(property != null);
if (PseudoCustomAttribute.IsDefined(property, caType))
return true;
return IsCustomAttributeDefined(property.Module, property.MetadataToken, caType);
}
internal static bool IsDefined(RuntimeEventInfo e, RuntimeType caType)
{
ASSERT.PRECONDITION(e != null);
if (PseudoCustomAttribute.IsDefined(e, caType))
return true;
return IsCustomAttributeDefined(e.Module, e.MetadataToken, caType);
}
internal static bool IsDefined(RuntimeFieldInfo field, RuntimeType caType)
{
ASSERT.PRECONDITION(field != null);
if (PseudoCustomAttribute.IsDefined(field, caType))
return true;
return IsCustomAttributeDefined(field.Module, field.MetadataToken, caType);
}
internal static bool IsDefined(ParameterInfo parameter, RuntimeType caType)
{
if (PseudoCustomAttribute.IsDefined(parameter, caType))
return true;
return IsCustomAttributeDefined(parameter.Member.Module, parameter.MetadataToken, caType);
}
internal static bool IsDefined(Assembly assembly, RuntimeType caType)
{
if (PseudoCustomAttribute.IsDefined(assembly, caType))
return true;
return IsCustomAttributeDefined(assembly.ManifestModule, assembly.AssemblyHandle.GetToken(), caType);
}
internal static bool IsDefined(Module module, RuntimeType caType)
{
if (PseudoCustomAttribute.IsDefined(module, caType))
return true;
return IsCustomAttributeDefined(module, module.MetadataToken, caType);
}
internal static Object[] GetCustomAttributes(RuntimeType type, RuntimeType caType, bool inherit)
{
if (type.GetElementType() != null)
return (caType.IsValueType) ? new object[0] : (Object[])Array.CreateInstance(caType, 0);
if (type.IsGenericType && !type.IsGenericTypeDefinition)
type = type.GetGenericTypeDefinition() as RuntimeType;
int pcaCount = 0;
Attribute[] pca = PseudoCustomAttribute.GetCustomAttributes(type, caType, true, out pcaCount);
// if we are asked to go up the hierarchy chain we have to do it now and regardless of the
// attribute usage for the specific attribute because a derived attribute may override the usage...
// ... however if the attribute is sealed we can rely on the attribute usage
if (!inherit || (caType.IsSealed && !CustomAttribute.GetAttributeUsage(caType).Inherited))
{
object[] attributes = GetCustomAttributes(type.Module, type.MetadataToken, pcaCount, caType);
if (pcaCount > 0) Array.Copy(pca, 0, attributes, attributes.Length - pcaCount, pcaCount);
return attributes;
}
List