Main Page | Modules | Class Hierarchy | Data Structures | Directories | File List | Data Fields | Related Pages

Dict.cs

00001 using System;
00002 using System.Collections;
00003 using System.Runtime.InteropServices;
00004 using System.Reflection.Emit;
00005 
00006 using DBus;
00007 
00008 namespace DBus.DBusType
00009 {
00013   public class Dict : IDBusType
00014   {
00015     public const char Code = 'm';
00016     private Hashtable val;
00017     
00018     private Dict()
00019     {
00020     }
00021     
00022     public Dict(IDictionary val, Service service)
00023     {
00024       this.val = new Hashtable();
00025       foreach (DictionaryEntry entry in val) {
00026         this.val.Add(entry.Key, entry.Value);
00027       }
00028     }
00029 
00030     public Dict(IntPtr iter, Service service)
00031     {
00032       IntPtr dictIter = Marshal.AllocCoTaskMem(Arguments.DBusMessageIterSize);
00033       
00034       bool notEmpty = dbus_message_iter_init_dict_iterator(iter, dictIter);
00035 
00036       this.val = new Hashtable();
00037 
00038       if (notEmpty) {
00039         do {
00040           string key = dbus_message_iter_get_dict_key(dictIter);
00041           
00042           // Get the argument type and get the value
00043           Type elementType = (Type) DBus.Arguments.DBusTypes[(char) dbus_message_iter_get_arg_type(dictIter)];
00044           object [] pars = new Object[2];
00045           pars[0] = dictIter;
00046           pars[1] = service;
00047           DBusType.IDBusType dbusType = (DBusType.IDBusType) Activator.CreateInstance(elementType, pars);
00048           this.val.Add(key, dbusType);
00049         } while (dbus_message_iter_next(dictIter));
00050       }
00051       
00052       Marshal.FreeCoTaskMem(dictIter);
00053     }
00054     
00055     public void Append(IntPtr iter)
00056     {
00057       IntPtr dictIter = Marshal.AllocCoTaskMem(Arguments.DBusMessageIterSize);
00058 
00059       if (!dbus_message_iter_append_dict(iter,
00060                                          dictIter)) {
00061         throw new ApplicationException("Failed to append DICT argument:" + val);
00062       }
00063 
00064       foreach (DictionaryEntry entry in this.val) {
00065         if (!dbus_message_iter_append_dict_key(dictIter, (string) entry.Key)) {
00066           throw new ApplicationException("Failed to append DICT key:" + entry.Key);
00067         }
00068         
00069         // Get the element type
00070         Type elementType = Arguments.MatchType(entry.Value.GetType());
00071         object [] pars = new Object[1];
00072         pars[0] = entry.Value;
00073         DBusType.IDBusType dbusType = (DBusType.IDBusType) Activator.CreateInstance(elementType, pars);
00074         dbusType.Append(dictIter);
00075       }
00076 
00077       Marshal.FreeCoTaskMem(dictIter);
00078     }    
00079 
00080     public static bool Suits(System.Type type) 
00081     {
00082       if (typeof(IDictionary).IsAssignableFrom(type)) {
00083         return true;
00084       }
00085             
00086       return false;
00087     }
00088 
00089     public static void EmitMarshalIn(ILGenerator generator, Type type)
00090     {
00091       if (type.IsByRef) {
00092         generator.Emit(OpCodes.Ldind_Ref);
00093       }
00094     }
00095 
00096     public static void EmitMarshalOut(ILGenerator generator, Type type, bool isReturn) 
00097     {
00098       generator.Emit(OpCodes.Castclass, type);
00099       if (!isReturn) {
00100         generator.Emit(OpCodes.Stind_Ref);
00101       }
00102     }
00103     
00104     public object Get() 
00105     {
00106       return Get(typeof(Hashtable));
00107     }
00108 
00109     public object Get(System.Type type)
00110     {
00111       IDictionary retVal;
00112 
00113       if (Suits(type)) {
00114         retVal = (IDictionary) Activator.CreateInstance(type, new object[0]);
00115         foreach (DictionaryEntry entry in this.val) {
00116           retVal.Add(entry.Key, ((IDBusType) entry.Value).Get());
00117         }
00118       } else {
00119         throw new ArgumentException("Cannot cast DBus.Type.Dict to type '" + type.ToString() + "'");
00120       }
00121         
00122       return retVal;
00123     }    
00124 
00125     [DllImport("dbus-1")]
00126     private extern static bool dbus_message_iter_init_dict_iterator(IntPtr iter,
00127                                                                     IntPtr dictIter);
00128  
00129     [DllImport("dbus-1")]
00130     private extern static bool dbus_message_iter_append_dict(IntPtr iter, 
00131                                                              IntPtr dictIter);
00132 
00133     [DllImport("dbus-1")]
00134     private extern static bool dbus_message_iter_has_next(IntPtr iter);
00135 
00136     [DllImport("dbus-1")]
00137     private extern static bool dbus_message_iter_next(IntPtr iter);
00138 
00139     [DllImport("dbus-1")]
00140     private extern static string dbus_message_iter_get_dict_key (IntPtr dictIter);  
00141 
00142     [DllImport("dbus-1")]
00143     private extern static bool dbus_message_iter_append_dict_key (IntPtr dictIter,
00144                                                                   string value);
00145     [DllImport("dbus-1")]
00146     private extern static int dbus_message_iter_get_arg_type(IntPtr iter);
00147   }
00148 }

Generated on Tue Mar 22 19:11:26 2005 for D-BUS by  doxygen 1.4.1