2003-02-28 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                         data = GetBlob (con, constructorArgs, namedProperties, propertyValues, namedFields, fieldValues);
51                 }
52
53                 /* helper methods */
54                 internal static int decode_len (byte[] data, int pos, out int rpos) {
55                         int len = 0;
56                         if ((data [pos] & 0x80) == 0) {
57                                 len = (int)(data [pos++] & 0x7f);
58                         } else if ((data [pos] & 0x40) == 0) {
59                                 len = ((data [pos] & 0x3f) << 8) + data [pos + 1];
60                                 pos += 2;
61                         } else {
62                                 len = ((data [pos] & 0x1f) << 24) + (data [pos + 1] << 16) + (data [pos + 2] << 8) + data [pos + 3];
63                                 pos += 4;
64                         }
65                         rpos = pos;
66                         return len;
67                 }
68
69                 internal static string string_from_bytes (byte[] data, int pos, int len) 
70                 {
71                         return System.Text.Encoding.UTF8.GetString(data, pos, len);
72                 }
73
74                 internal static UnmanagedMarshal get_umarshal (CustomAttributeBuilder customBuilder, bool is_field) {
75                         byte[] data = customBuilder.Data;
76                         UnmanagedType subtype = UnmanagedType.I4;
77                         int sizeConst = 0;
78                         int value;
79                         int utype; /* the (stupid) ctor takes a short or an enum ... */
80                         utype = (int)data [2];
81                         utype |= ((int)data [3]) << 8;
82
83                         string first_type_name = customBuilder.Ctor.GetParameters()[0].ParameterType.FullName;
84                         int pos = 6;
85                         if (first_type_name == "System.Int16")
86                                 pos = 4;
87                         int nnamed = (int)data [pos++];
88                         nnamed |= ((int)data [pos++]) << 8;
89                         
90                         for (int i = 0; i < nnamed; ++i) {
91                                 int paramType; // What is this ?
92                                 paramType = (int)data [pos++];
93                                 paramType |= ((int)data [pos++]) << 8;
94                                 int len = decode_len (data, pos, out pos);
95                                 string named_name = string_from_bytes (data, pos, len);
96                                 pos += len;
97
98                                 switch (named_name) {
99                                 case "ArraySubType":
100                                         value = (int)data [pos++];
101                                         value |= ((int)data [pos++]) << 8;
102                                         value |= ((int)data [pos++]) << 16;
103                                         value |= ((int)data [pos++]) << 24;
104                                         subtype = (UnmanagedType)value;
105                                         break;
106                                 case "SizeConst":
107                                         value = (int)data [pos++];
108                                         value |= ((int)data [pos++]) << 8;
109                                         value |= ((int)data [pos++]) << 16;
110                                         value |= ((int)data [pos++]) << 24;
111                                         sizeConst = value;
112                                         break;
113                                 default:
114                                         break;
115                                 }
116                         }
117
118                         switch ((UnmanagedType)utype) {
119                         case UnmanagedType.LPArray:
120                                 return UnmanagedMarshal.DefineLPArray (subtype);
121                         case UnmanagedType.SafeArray:
122                                 return UnmanagedMarshal.DefineSafeArray (subtype);
123                         case UnmanagedType.ByValArray:
124                                 return UnmanagedMarshal.DefineByValArray (sizeConst);
125                         case UnmanagedType.ByValTStr:
126                                 return UnmanagedMarshal.DefineByValTStr (sizeConst);
127                         default:
128                                 return UnmanagedMarshal.DefineUnmanagedMarshal ((UnmanagedType)utype);
129                         }
130                 }
131
132         }
133 }