2 using System.Collections;
3 using System.Runtime.InteropServices;
4 using System.Reflection.Emit;
8 namespace DBus.DBusType
13 public class Array : IDBusType
15 public const char Code = 'a';
16 private System.Array val;
17 private ArrayList elements;
18 private Type elementType;
19 private Service service = null;
25 public Array(System.Array val, Service service)
28 this.elementType = Arguments.MatchType(val.GetType().UnderlyingSystemType);
29 this.service = service;
32 public Array(IntPtr iter, Service service)
34 this.service = service;
36 IntPtr arrayIter = Marshal.AllocCoTaskMem(Arguments.DBusMessageIterSize);
39 dbus_message_iter_init_array_iterator(iter, arrayIter, out elementTypeCode);
40 this.elementType = (Type) Arguments.DBusTypes[(char) elementTypeCode];
42 elements = new ArrayList();
45 object [] pars = new Object[2];
48 DBusType.IDBusType dbusType = (DBusType.IDBusType) Activator.CreateInstance(elementType, pars);
49 elements.Add(dbusType);
50 } while (dbus_message_iter_next(arrayIter));
52 Marshal.FreeCoTaskMem(arrayIter);
55 public void Append(IntPtr iter)
57 IntPtr arrayIter = Marshal.AllocCoTaskMem(Arguments.DBusMessageIterSize);
59 if (!dbus_message_iter_append_array(iter,
61 (int) Arguments.GetCode(this.elementType))) {
62 throw new ApplicationException("Failed to append INT32 argument:" + val);
65 foreach (object element in this.val) {
66 object [] pars = new Object[2];
68 pars[1] = this.service;
69 DBusType.IDBusType dbusType = (DBusType.IDBusType) Activator.CreateInstance(elementType, pars);
70 dbusType.Append(arrayIter);
73 Marshal.FreeCoTaskMem(arrayIter);
76 public static bool Suits(System.Type type)
85 public static void EmitMarshalIn(ILGenerator generator, Type type)
88 generator.Emit(OpCodes.Ldind_Ref);
92 public static void EmitMarshalOut(ILGenerator generator, Type type, bool isReturn)
94 generator.Emit(OpCodes.Castclass, type);
96 generator.Emit(OpCodes.Stind_Ref);
102 throw new ArgumentException("Cannot call Get on an Array without specifying type.");
105 public object Get(System.Type type)
107 if (Arguments.Suits(elementType, type.UnderlyingSystemType)) {
108 this.val = System.Array.CreateInstance(type.UnderlyingSystemType, elements.Count);
110 foreach (DBusType.IDBusType element in elements) {
111 this.val.SetValue(element.Get(type.UnderlyingSystemType), i++);
114 throw new ArgumentException("Cannot cast DBus.Type.Array to type '" + type.ToString() + "'");
120 [DllImport("dbus-1")]
121 private extern static void dbus_message_iter_init_array_iterator(IntPtr iter,
123 out int elementType);
125 [DllImport("dbus-1")]
126 private extern static bool dbus_message_iter_append_array(IntPtr iter,
130 [DllImport("dbus-1")]
131 private extern static bool dbus_message_iter_has_next(IntPtr iter);
133 [DllImport("dbus-1")]
134 private extern static bool dbus_message_iter_next(IntPtr iter);