3 // System.Reflection.Emit/CustomAttributeBuilder.cs
6 // Paolo Molaro (lupus@ximian.com)
8 // (C) 2001 Ximian, Inc. http://www.ximian.com
12 using System.Reflection;
13 using System.Reflection.Emit;
14 using System.Runtime.CompilerServices;
15 using System.Runtime.InteropServices;
17 namespace System.Reflection.Emit {
18 public class CustomAttributeBuilder {
22 internal ConstructorInfo Ctor {
26 internal byte[] Data {
30 [MethodImplAttribute(MethodImplOptions.InternalCall)]
31 static extern byte[] GetBlob(ConstructorInfo con, object[] constructorArgs, PropertyInfo[] namedProperties, object[] propertyValues, FieldInfo[] namedFields, object[] fieldValues);
33 internal CustomAttributeBuilder( ConstructorInfo con, byte[] cdata) {
35 data = (byte[])cdata.Clone ();
36 /* should we check that the user supplied data is correct? */
39 public CustomAttributeBuilder( ConstructorInfo con, object[] constructorArgs)
40 : this (con, constructorArgs, null, null, null, null) {
42 public CustomAttributeBuilder( ConstructorInfo con, object[] constructorArgs, FieldInfo[] namedFields, object[] fieldValues)
43 : this (con, constructorArgs, null, null, namedFields, fieldValues) {
45 public CustomAttributeBuilder( ConstructorInfo con, object[] constructorArgs, PropertyInfo[] namedProperties, object[] propertyValues)
46 : this (con, constructorArgs, namedProperties, propertyValues, null, null) {
48 public CustomAttributeBuilder( ConstructorInfo con, object[] constructorArgs, PropertyInfo[] namedProperties, object[] propertyValues, FieldInfo[] namedFields, object[] fieldValues) {
50 if (constructorArgs == null)
51 throw new ArgumentNullException ("constructorArgs");
52 data = GetBlob (con, constructorArgs, namedProperties, propertyValues, namedFields, fieldValues);
56 internal static int decode_len (byte[] data, int pos, out int rpos) {
58 if ((data [pos] & 0x80) == 0) {
59 len = (int)(data [pos++] & 0x7f);
60 } else if ((data [pos] & 0x40) == 0) {
61 len = ((data [pos] & 0x3f) << 8) + data [pos + 1];
64 len = ((data [pos] & 0x1f) << 24) + (data [pos + 1] << 16) + (data [pos + 2] << 8) + data [pos + 3];
71 internal static string string_from_bytes (byte[] data, int pos, int len)
73 return System.Text.Encoding.UTF8.GetString(data, pos, len);
76 internal string string_arg ()
79 int len = decode_len (data, pos, out pos);
80 return string_from_bytes (data, pos, len);
83 internal static UnmanagedMarshal get_umarshal (CustomAttributeBuilder customBuilder, bool is_field) {
84 byte[] data = customBuilder.Data;
85 UnmanagedType subtype = UnmanagedType.I4;
88 int utype; /* the (stupid) ctor takes a short or an enum ... */
89 utype = (int)data [2];
90 utype |= ((int)data [3]) << 8;
92 string first_type_name = customBuilder.Ctor.GetParameters()[0].ParameterType.FullName;
94 if (first_type_name == "System.Int16")
96 int nnamed = (int)data [pos++];
97 nnamed |= ((int)data [pos++]) << 8;
99 for (int i = 0; i < nnamed; ++i) {
100 int paramType; // What is this ?
101 paramType = (int)data [pos++];
102 paramType |= ((int)data [pos++]) << 8;
103 int len = decode_len (data, pos, out pos);
104 string named_name = string_from_bytes (data, pos, len);
107 switch (named_name) {
109 value = (int)data [pos++];
110 value |= ((int)data [pos++]) << 8;
111 value |= ((int)data [pos++]) << 16;
112 value |= ((int)data [pos++]) << 24;
113 subtype = (UnmanagedType)value;
116 value = (int)data [pos++];
117 value |= ((int)data [pos++]) << 8;
118 value |= ((int)data [pos++]) << 16;
119 value |= ((int)data [pos++]) << 24;
127 switch ((UnmanagedType)utype) {
128 case UnmanagedType.LPArray:
129 return UnmanagedMarshal.DefineLPArray (subtype);
130 case UnmanagedType.SafeArray:
131 return UnmanagedMarshal.DefineSafeArray (subtype);
132 case UnmanagedType.ByValArray:
133 return UnmanagedMarshal.DefineByValArray (sizeConst);
134 case UnmanagedType.ByValTStr:
135 return UnmanagedMarshal.DefineByValTStr (sizeConst);
137 return UnmanagedMarshal.DefineUnmanagedMarshal ((UnmanagedType)utype);