+static void
+get_prop_name_and_type (MonoObject *prop, char **name, MonoType **type)
+{
+ MonoClass *klass = mono_object_class (prop);
+ if (strcmp (klass->name, "PropertyBuilder") == 0) {
+ MonoReflectionPropertyBuilder *pb = (MonoReflectionPropertyBuilder *)prop;
+ *name = mono_string_to_utf8 (pb->name);
+ *type = pb->type->type;
+ } else {
+ MonoReflectionProperty *p = (MonoReflectionProperty *)prop;
+ *name = g_strdup (p->property->name);
+ if (p->property->get)
+ *type = p->property->get->signature->ret;
+ else
+ *type = p->property->set->signature->params [p->property->set->signature->param_count - 1];
+ }
+}
+
+static void
+get_field_name_and_type (MonoObject *field, char **name, MonoType **type)
+{
+ MonoClass *klass = mono_object_class (field);
+ if (strcmp (klass->name, "FieldBuilder") == 0) {
+ MonoReflectionFieldBuilder *fb = (MonoReflectionFieldBuilder *)field;
+ *name = mono_string_to_utf8 (fb->name);
+ *type = fb->type->type;
+ } else {
+ MonoReflectionField *f = (MonoReflectionField *)field;
+ *name = g_strdup (f->field->name);
+ *type = f->field->type;
+ }
+}
+
+static void
+encode_cattr_value (char *buffer, char *p, char **retbuffer, char **retp, guint32 *buflen, MonoType *type, MonoObject *arg)
+{
+ char *argval;
+ MonoTypeEnum simple_type;
+
+ if ((p-buffer) + 10 >= *buflen) {
+ char *newbuf;
+ *buflen *= 2;
+ newbuf = g_realloc (buffer, *buflen);
+ p = newbuf + (p-buffer);
+ buffer = newbuf;
+ }
+ argval = ((char*)arg + sizeof (MonoObject));
+ simple_type = type->type;
+handle_enum:
+ switch (simple_type) {
+ case MONO_TYPE_BOOLEAN:
+ case MONO_TYPE_U1:
+ case MONO_TYPE_I1:
+ *p++ = *argval;
+ break;
+ case MONO_TYPE_CHAR:
+ case MONO_TYPE_U2:
+ case MONO_TYPE_I2:
+ swap_with_size (p, argval, 2, 1);
+ p += 2;
+ break;
+ case MONO_TYPE_U4:
+ case MONO_TYPE_I4:
+ case MONO_TYPE_R4:
+ swap_with_size (p, argval, 4, 1);
+ p += 4;
+ break;
+ case MONO_TYPE_U8:
+ case MONO_TYPE_I8:
+ case MONO_TYPE_R8:
+ swap_with_size (p, argval, 8, 1);
+ p += 8;
+ break;
+ case MONO_TYPE_VALUETYPE:
+ if (type->data.klass->enumtype) {
+ simple_type = type->data.klass->enum_basetype->type;
+ goto handle_enum;
+ } else {
+ g_warning ("generic valutype %s not handled in custom attr value decoding", type->data.klass->name);
+ }
+ break;
+ case MONO_TYPE_STRING: {
+ char *str = mono_string_to_utf8 ((MonoString*)arg);
+ guint32 slen = strlen (str);
+ if ((p-buffer) + 10 + slen >= *buflen) {
+ char *newbuf;
+ *buflen *= 2;
+ *buflen += slen;
+ newbuf = g_realloc (buffer, *buflen);
+ p = newbuf + (p-buffer);
+ buffer = newbuf;
+ }
+ mono_metadata_encode_value (slen, p, &p);
+ memcpy (p, str, slen);
+ p += slen;
+ g_free (str);
+ break;
+ }
+ default:
+ g_error ("type 0x%02x not yet supported in custom attr encoder", simple_type);
+ }
+ *retp = p;
+ *retbuffer = buffer;
+}
+