2 using System.Collections;
3 using System.Runtime.InteropServices;
4 using System.Reflection.Emit;
8 namespace DBus.DBusType
13 public class Dict : IDBusType
15 public const char Code = 'm';
16 private Hashtable val;
22 public Dict(IDictionary val, Service service)
24 this.val = new Hashtable();
25 foreach (DictionaryEntry entry in val) {
26 this.val.Add(entry.Key, entry.Value);
30 public Dict(IntPtr iter, Service service)
32 IntPtr dictIter = Marshal.AllocCoTaskMem(Arguments.DBusMessageIterSize);
34 bool notEmpty = dbus_message_iter_init_dict_iterator(iter, dictIter);
36 this.val = new Hashtable();
40 string key = dbus_message_iter_get_dict_key(dictIter);
42 // Get the argument type and get the value
43 Type elementType = (Type) DBus.Arguments.DBusTypes[(char) dbus_message_iter_get_arg_type(dictIter)];
44 object [] pars = new Object[2];
47 DBusType.IDBusType dbusType = (DBusType.IDBusType) Activator.CreateInstance(elementType, pars);
48 this.val.Add(key, dbusType);
49 } while (dbus_message_iter_next(dictIter));
52 Marshal.FreeCoTaskMem(dictIter);
55 public void Append(IntPtr iter)
57 IntPtr dictIter = Marshal.AllocCoTaskMem(Arguments.DBusMessageIterSize);
59 if (!dbus_message_iter_append_dict(iter,
61 throw new ApplicationException("Failed to append DICT argument:" + val);
64 foreach (DictionaryEntry entry in this.val) {
65 if (!dbus_message_iter_append_dict_key(dictIter, (string) entry.Key)) {
66 throw new ApplicationException("Failed to append DICT key:" + entry.Key);
69 // Get the element type
70 Type elementType = Arguments.MatchType(entry.Value.GetType());
71 object [] pars = new Object[1];
72 pars[0] = entry.Value;
73 DBusType.IDBusType dbusType = (DBusType.IDBusType) Activator.CreateInstance(elementType, pars);
74 dbusType.Append(dictIter);
77 Marshal.FreeCoTaskMem(dictIter);
80 public static bool Suits(System.Type type)
82 if (typeof(IDictionary).IsAssignableFrom(type)) {
89 public static void EmitMarshalIn(ILGenerator generator, Type type)
92 generator.Emit(OpCodes.Ldind_Ref);
96 public static void EmitMarshalOut(ILGenerator generator, Type type, bool isReturn)
98 generator.Emit(OpCodes.Castclass, type);
100 generator.Emit(OpCodes.Stind_Ref);
106 return Get(typeof(Hashtable));
109 public object Get(System.Type type)
114 retVal = (IDictionary) Activator.CreateInstance(type, new object[0]);
115 foreach (DictionaryEntry entry in this.val) {
116 retVal.Add(entry.Key, ((IDBusType) entry.Value).Get());
119 throw new ArgumentException("Cannot cast DBus.Type.Dict to type '" + type.ToString() + "'");
125 [DllImport("dbus-1")]
126 private extern static bool dbus_message_iter_init_dict_iterator(IntPtr iter,
129 [DllImport("dbus-1")]
130 private extern static bool dbus_message_iter_append_dict(IntPtr iter,
133 [DllImport("dbus-1")]
134 private extern static bool dbus_message_iter_has_next(IntPtr iter);
136 [DllImport("dbus-1")]
137 private extern static bool dbus_message_iter_next(IntPtr iter);
139 [DllImport("dbus-1")]
140 private extern static string dbus_message_iter_get_dict_key (IntPtr dictIter);
142 [DllImport("dbus-1")]
143 private extern static bool dbus_message_iter_append_dict_key (IntPtr dictIter,
145 [DllImport("dbus-1")]
146 private extern static int dbus_message_iter_get_arg_type(IntPtr iter);