1 // 2 // System.Reflection/CustomAttributeData.cs 3 // 4 // Author: 5 // Zoltan Varga (vargaz@gmail.com) 6 // Carlos Alberto Cortez (calberto.cortez@gmail.com) 7 // 8 // Copyright (C) 2004 Novell, Inc (http://www.novell.com) 9 // 10 // Permission is hereby granted, free of charge, to any person obtaining 11 // a copy of this software and associated documentation files (the 12 // "Software"), to deal in the Software without restriction, including 13 // without limitation the rights to use, copy, modify, merge, publish, 14 // distribute, sublicense, and/or sell copies of the Software, and to 15 // permit persons to whom the Software is furnished to do so, subject to 16 // the following conditions: 17 // 18 // The above copyright notice and this permission notice shall be 19 // included in all copies or substantial portions of the Software. 20 // 21 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 22 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 23 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 24 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 25 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 26 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 27 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 28 // 29 30 using System; 31 using System.Collections.Generic; 32 using System.Runtime.CompilerServices; 33 using System.Runtime.InteropServices; 34 using System.Text; 35 36 namespace System.Reflection { 37 38 [ComVisible (true)] 39 [Serializable] 40 public 41 class CustomAttributeData { 42 class LazyCAttrData { 43 internal Assembly assembly; 44 internal IntPtr data; 45 internal uint data_length; 46 } 47 48 ConstructorInfo ctorInfo; 49 IList<CustomAttributeTypedArgument> ctorArgs; 50 IList<CustomAttributeNamedArgument> namedArgs; 51 LazyCAttrData lazyData; 52 53 CustomAttributeData()54 protected CustomAttributeData () 55 { 56 } 57 CustomAttributeData(ConstructorInfo ctorInfo, Assembly assembly, IntPtr data, uint data_length)58 internal CustomAttributeData (ConstructorInfo ctorInfo, Assembly assembly, IntPtr data, uint data_length) 59 { 60 this.ctorInfo = ctorInfo; 61 this.lazyData = new LazyCAttrData (); 62 this.lazyData.assembly = assembly; 63 this.lazyData.data = data; 64 this.lazyData.data_length = data_length; 65 } 66 67 [MethodImplAttribute (MethodImplOptions.InternalCall)] ResolveArgumentsInternal(ConstructorInfo ctor, Assembly assembly, IntPtr data, uint data_length, out object[] ctorArgs, out object[] namedArgs)68 static extern void ResolveArgumentsInternal (ConstructorInfo ctor, Assembly assembly, IntPtr data, uint data_length, out object[] ctorArgs, out object[] namedArgs); 69 ResolveArguments()70 void ResolveArguments () 71 { 72 object[] ctor_args, named_args; 73 if (lazyData == null) 74 return; 75 76 ResolveArgumentsInternal (ctorInfo, lazyData.assembly, lazyData.data, lazyData.data_length, out ctor_args, out named_args); 77 78 this.ctorArgs = Array.AsReadOnly<CustomAttributeTypedArgument> 79 (ctor_args != null ? UnboxValues<CustomAttributeTypedArgument> (ctor_args) : EmptyArray<CustomAttributeTypedArgument>.Value); 80 this.namedArgs = Array.AsReadOnly<CustomAttributeNamedArgument> 81 (named_args != null ? UnboxValues<CustomAttributeNamedArgument> (named_args) : EmptyArray<CustomAttributeNamedArgument>.Value); 82 83 lazyData = null; 84 } 85 86 [ComVisible (true)] 87 public 88 virtual 89 ConstructorInfo Constructor { 90 get { 91 return ctorInfo; 92 } 93 } 94 95 [ComVisible (true)] 96 public 97 virtual 98 IList<CustomAttributeTypedArgument> ConstructorArguments { 99 get { 100 ResolveArguments (); 101 return ctorArgs; 102 } 103 } 104 105 public 106 virtual 107 IList<CustomAttributeNamedArgument> NamedArguments { 108 get { 109 ResolveArguments (); 110 return namedArgs; 111 } 112 } 113 GetCustomAttributes(Assembly target)114 public static IList<CustomAttributeData> GetCustomAttributes (Assembly target) { 115 return MonoCustomAttrs.GetCustomAttributesData (target); 116 } 117 GetCustomAttributes(MemberInfo target)118 public static IList<CustomAttributeData> GetCustomAttributes (MemberInfo target) { 119 return MonoCustomAttrs.GetCustomAttributesData (target); 120 } 121 GetCustomAttributesInternal(RuntimeType target)122 internal static IList<CustomAttributeData> GetCustomAttributesInternal (RuntimeType target) { 123 return MonoCustomAttrs.GetCustomAttributesData (target); 124 } 125 GetCustomAttributes(Module target)126 public static IList<CustomAttributeData> GetCustomAttributes (Module target) { 127 return MonoCustomAttrs.GetCustomAttributesData (target); 128 } 129 GetCustomAttributes(ParameterInfo target)130 public static IList<CustomAttributeData> GetCustomAttributes (ParameterInfo target) { 131 return MonoCustomAttrs.GetCustomAttributesData (target); 132 } 133 134 public Type AttributeType { 135 get { return ctorInfo.DeclaringType; } 136 } 137 ToString()138 public override string ToString () 139 { 140 ResolveArguments (); 141 142 StringBuilder sb = new StringBuilder (); 143 144 sb.Append ("[" + ctorInfo.DeclaringType.FullName + "("); 145 for (int i = 0; i < ctorArgs.Count; i++) { 146 sb.Append (ctorArgs [i].ToString ()); 147 if (i + 1 < ctorArgs.Count) 148 sb.Append (", "); 149 } 150 151 if (namedArgs.Count > 0) 152 sb.Append (", "); 153 154 for (int j = 0; j < namedArgs.Count; j++) { 155 sb.Append (namedArgs [j].ToString ()); 156 if (j + 1 < namedArgs.Count) 157 sb.Append (", "); 158 } 159 sb.AppendFormat (")]"); 160 161 return sb.ToString (); 162 } 163 UnboxValues(object [] values)164 static T [] UnboxValues<T> (object [] values) 165 { 166 T [] retval = new T [values.Length]; 167 for (int i = 0; i < values.Length; i++) 168 retval [i] = (T) values [i]; 169 170 return retval; 171 } 172 Equals(object obj)173 public override bool Equals (object obj) 174 { 175 CustomAttributeData other = obj as CustomAttributeData; 176 if (other == null || other.ctorInfo != ctorInfo || 177 other.ctorArgs.Count != ctorArgs.Count || 178 other.namedArgs.Count != namedArgs.Count) 179 return false; 180 for (int i = 0; i < ctorArgs.Count; i++) 181 if (ctorArgs [i].Equals (other.ctorArgs [i])) 182 return false; 183 for (int i = 0; i < namedArgs.Count; i++) { 184 bool matched = false; 185 for (int j = 0; j < other.namedArgs.Count; j++) 186 if (namedArgs [i].Equals (other.namedArgs [j])) { 187 matched = true; 188 break; 189 } 190 if (!matched) 191 return false; 192 } 193 return true; 194 } 195 GetHashCode()196 public override int GetHashCode () 197 { 198 int ret = ctorInfo == null ? 13 : (ctorInfo.GetHashCode () << 16); 199 // argument order-dependent 200 if (ctorArgs != null) { 201 for (int i = 0; i < ctorArgs.Count; i++) { 202 ret += ret ^ 7 + ctorArgs [i].GetHashCode () << (i * 4); 203 } 204 } 205 // argument order-independent 206 if (namedArgs != null) { 207 for (int i = 0; i < namedArgs.Count; i++) 208 ret += (namedArgs [i].GetHashCode () << 5); 209 } 210 return ret; 211 } 212 } 213 214 } 215 216