Author: zoltan
Date: 2005-06-01 15:36:34 -0400 (Wed, 01 Jun 2005)
New Revision: 45307

Modified:
   trunk/mcs/class/corlib/System.Reflection.Emit/ChangeLog
   trunk/mcs/class/corlib/System.Reflection.Emit/CustomAttributeBuilder.cs
Log:
2005-06-01  Zoltan Varga  <[EMAIL PROTECTED]>

        * CustomAttributeBuilder.cs: Add a decode_cattr helper method.


Modified: trunk/mcs/class/corlib/System.Reflection.Emit/ChangeLog
===================================================================
--- trunk/mcs/class/corlib/System.Reflection.Emit/ChangeLog     2005-06-01 
19:33:53 UTC (rev 45306)
+++ trunk/mcs/class/corlib/System.Reflection.Emit/ChangeLog     2005-06-01 
19:36:34 UTC (rev 45307)
@@ -1,3 +1,7 @@
+2005-06-01  Zoltan Varga  <[EMAIL PROTECTED]>
+
+       * CustomAttributeBuilder.cs: Add a decode_cattr helper method.
+
 2005-05-27  Vladimir Vukicevic  <[EMAIL PROTECTED]>
 
        * MethodBuilder.cs: Add extra_flags field to encode P/Invoke

Modified: 
trunk/mcs/class/corlib/System.Reflection.Emit/CustomAttributeBuilder.cs
===================================================================
--- trunk/mcs/class/corlib/System.Reflection.Emit/CustomAttributeBuilder.cs     
2005-06-01 19:33:53 UTC (rev 45306)
+++ trunk/mcs/class/corlib/System.Reflection.Emit/CustomAttributeBuilder.cs     
2005-06-01 19:36:34 UTC (rev 45307)
@@ -294,5 +294,80 @@
                        }
                }
 
+               static object decode_cattr_value (Type t, byte[] data, int pos, 
out int rpos) {
+                       switch (Type.GetTypeCode (t)) {
+                       case TypeCode.String:
+                               int len = decode_len (data, pos, out pos);
+                               rpos = pos + len;
+                               return string_from_bytes (data, pos, len);
+                       case TypeCode.Int32:
+                               rpos = pos + 4;
+                               return data [pos] + (data [pos + 1] << 8) + 
(data [pos + 2] << 16) + (data [pos + 3] << 24);
+                       case TypeCode.Boolean:
+                               rpos = pos + 1;
+                               return (data [pos] == 0) ? false : true;
+                       default:
+                               throw new Exception ("FIXME: Type " + t + " not 
yet handled in decode_cattr_value.");
+                       }
+               }
+
+               internal static object decode_cattr (CustomAttributeBuilder 
customBuilder) {
+                       byte[] data = customBuilder.Data;
+                       ConstructorInfo ctor = customBuilder.Ctor;
+                       int pos = 0;
+
+                       // Prolog
+                       if (data.Length < 2)
+                               throw new Exception ();
+                       if ((data [0] != 0x1) || (data [1] != 0x00))
+                               throw new Exception ();
+                       pos = 2;
+
+                       ParameterInfo [] pi = ctor.GetParameters ();
+                       object[] ctorArgs = new object [pi.Length];
+                       for (int i = 0; i < pi.Length; ++i)
+                               ctorArgs [i] = decode_cattr_value (pi 
[i].ParameterType, data, pos, out pos);
+
+                       object res = ctor.Invoke (ctorArgs);
+
+                       int num_named = data [pos] + (data [pos + 1] * 256);
+                       pos += 2;
+
+                       for (int i = 0; i < num_named; ++i) {
+                               int named_type = data [pos++];
+                               int data_type = data [pos++];
+                               string enum_type_name = null;
+
+                               if (data_type == 0x55) {
+                                       int len2 = decode_len (data, pos, out 
pos);
+                                       enum_type_name = string_from_bytes 
(data, pos, len2);
+                                       pos += len2;
+                               }
+
+                               int len = decode_len (data, pos, out pos);
+                               string name = string_from_bytes (data, pos, 
len);
+                               pos += len;
+
+                               if (named_type == 0x53) {
+                                       /* Field */
+                                       FieldInfo fi = 
ctor.DeclaringType.GetField (name, 
BindingFlags.Public|BindingFlags.NonPublic|BindingFlags.Instance);
+                                       if (fi == null)
+                                               throw new Exception ("Custom 
attribute type '" + ctor.DeclaringType + "' doesn't contain a field named '" + 
name + "'");
+
+                                       object val = decode_cattr_value 
(fi.FieldType, data, pos, out pos);
+                                       if (enum_type_name != null) {
+                                               Type enumType = Type.GetType 
(enum_type_name);
+                                               val = Enum.ToObject (enumType, 
val);
+                                       }
+
+                                       fi.SetValue (res, val);
+                               }
+                               else
+                                       // FIXME:
+                                       throw new Exception ();
+                       }
+
+                       return res;
+               }
        }
 }

_______________________________________________
Mono-patches maillist  -  [email protected]
http://lists.ximian.com/mailman/listinfo/mono-patches

Reply via email to