2004-01-08 Zoltan Varga <vargaz@freemail.hu>
[mono.git] / mcs / class / corlib / System.Reflection.Emit / CustomAttributeBuilder.cs
1
2 //
3 // System.Reflection.Emit/CustomAttributeBuilder.cs
4 //
5 // Author:
6 //   Paolo Molaro (lupus@ximian.com)
7 //
8 // (C) 2001 Ximian, Inc.  http://www.ximian.com
9 //
10
11 using System;
12 using System.Reflection;
13 using System.Reflection.Emit;
14 using System.Runtime.CompilerServices;
15 using System.Runtime.InteropServices;
16
17 namespace System.Reflection.Emit {
18         public class CustomAttributeBuilder {
19                 ConstructorInfo ctor;
20                 byte[] data;
21
22                 internal ConstructorInfo Ctor {
23                         get {return ctor;}
24                 }
25
26                 internal byte[] Data {
27                         get {return data;}
28                 }
29                 
30                 [MethodImplAttribute(MethodImplOptions.InternalCall)]
31                 static extern byte[] GetBlob(ConstructorInfo con, object[] constructorArgs, PropertyInfo[] namedProperties, object[] propertyValues, FieldInfo[] namedFields, object[] fieldValues);
32                 
33                 internal CustomAttributeBuilder( ConstructorInfo con, byte[] cdata) {
34                         ctor = con;
35                         data = (byte[])cdata.Clone ();
36                         /* should we check that the user supplied data is correct? */
37                 }
38                 
39                 public CustomAttributeBuilder( ConstructorInfo con, object[] constructorArgs)
40                         : this (con, constructorArgs, null, null, null, null) {
41                 }
42                 public CustomAttributeBuilder( ConstructorInfo con, object[] constructorArgs, FieldInfo[] namedFields, object[] fieldValues)
43                         : this (con, constructorArgs, null, null, namedFields, fieldValues) {
44                 }
45                 public CustomAttributeBuilder( ConstructorInfo con, object[] constructorArgs, PropertyInfo[] namedProperties, object[] propertyValues)
46                         : this (con, constructorArgs, namedProperties, propertyValues, null, null) {
47                 }
48                 public CustomAttributeBuilder( ConstructorInfo con, object[] constructorArgs, PropertyInfo[] namedProperties, object[] propertyValues, FieldInfo[] namedFields, object[] fieldValues) {
49                         ctor = con;
50                         if (constructorArgs == null)
51                                 throw new ArgumentNullException ("constructorArgs");
52                         data = GetBlob (con, constructorArgs, namedProperties, propertyValues, namedFields, fieldValues);
53                 }
54
55                 /* helper methods */
56                 internal static int decode_len (byte[] data, int pos, out int rpos) {
57                         int len = 0;
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];
62                                 pos += 2;
63                         } else {
64                                 len = ((data [pos] & 0x1f) << 24) + (data [pos + 1] << 16) + (data [pos + 2] << 8) + data [pos + 3];
65                                 pos += 4;
66                         }
67                         rpos = pos;
68                         return len;
69                 }
70
71                 internal static string string_from_bytes (byte[] data, int pos, int len) 
72                 {
73                         return System.Text.Encoding.UTF8.GetString(data, pos, len);
74                 }
75
76                 internal string string_arg ()
77                 {
78                         int pos = 2;
79                         int len = decode_len (data, pos, out pos);
80                         return string_from_bytes (data, pos, len);
81                 }                       
82
83                 internal static UnmanagedMarshal get_umarshal (CustomAttributeBuilder customBuilder, bool is_field) {
84                         byte[] data = customBuilder.Data;
85                         UnmanagedType subtype = UnmanagedType.I4;
86                         int sizeConst = 0;
87                         int value;
88                         int utype; /* the (stupid) ctor takes a short or an enum ... */
89                         utype = (int)data [2];
90                         utype |= ((int)data [3]) << 8;
91
92                         string first_type_name = customBuilder.Ctor.GetParameters()[0].ParameterType.FullName;
93                         int pos = 6;
94                         if (first_type_name == "System.Int16")
95                                 pos = 4;
96                         int nnamed = (int)data [pos++];
97                         nnamed |= ((int)data [pos++]) << 8;
98                         
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);
105                                 pos += len;
106
107                                 switch (named_name) {
108                                 case "ArraySubType":
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;
114                                         break;
115                                 case "SizeConst":
116                                         value = (int)data [pos++];
117                                         value |= ((int)data [pos++]) << 8;
118                                         value |= ((int)data [pos++]) << 16;
119                                         value |= ((int)data [pos++]) << 24;
120                                         sizeConst = value;
121                                         break;
122                                 default:
123                                         break;
124                                 }
125                         }
126
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);
136                         default:
137                                 return UnmanagedMarshal.DefineUnmanagedMarshal ((UnmanagedType)utype);
138                         }
139                 }
140
141         }
142 }