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

Array.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 Array : IDBusType
00014   {
00015     public const char Code = 'a';
00016     private System.Array val;
00017     private ArrayList elements;
00018     private Type elementType;
00019     private Service service = null;
00020     
00021     private Array()
00022     {
00023     }
00024     
00025     public Array(System.Array val, Service service) 
00026     {
00027       this.val = val;
00028       this.elementType = Arguments.MatchType(val.GetType().GetElementType());
00029       this.service = service;
00030     }
00031 
00032     public Array(IntPtr iter, Service service)
00033     {
00034       this.service = service;
00035 
00036       IntPtr arrayIter = Marshal.AllocCoTaskMem(Arguments.DBusMessageIterSize);
00037 
00038       int elementTypeCode = dbus_message_iter_get_element_type (iter);
00039       dbus_message_iter_recurse (iter, arrayIter);
00040       this.elementType = (Type) Arguments.DBusTypes [(char) elementTypeCode];
00041 
00042       elements = new ArrayList ();
00043 
00044       if (dbus_message_iter_get_arg_type (arrayIter) != 0) {
00045         do {
00046           object [] pars = new Object[2];
00047           pars[0] = arrayIter;
00048           pars[1] = service;
00049           DBusType.IDBusType dbusType = (DBusType.IDBusType) Activator.CreateInstance(elementType, pars);
00050           elements.Add(dbusType);
00051         } while (dbus_message_iter_next(arrayIter));
00052       }      
00053 
00054       Marshal.FreeCoTaskMem(arrayIter);
00055     }
00056     
00057     public void Append(IntPtr iter)
00058     {
00059       IntPtr arrayIter = Marshal.AllocCoTaskMem (Arguments.DBusMessageIterSize);
00060 
00061       if (!dbus_message_iter_open_container (iter,
00062                                              (int) Code,
00063                                              Arguments.GetCodeAsString (elementType),
00064                                              arrayIter)) {
00065         throw new ApplicationException("Failed to append array argument: " + val);
00066       }
00067       
00068       foreach (object element in this.val) {
00069         object [] pars = new Object[2];
00070         pars[0] = element;
00071         pars[1] = this.service;
00072         DBusType.IDBusType dbusType = (DBusType.IDBusType) Activator.CreateInstance(elementType, pars);
00073         dbusType.Append(arrayIter);
00074       }
00075 
00076       if (!dbus_message_iter_close_container (iter, arrayIter)) {
00077         throw new ApplicationException ("Failed to append array argument: " + val);
00078       }
00079 
00080       Marshal.FreeCoTaskMem (arrayIter);
00081     }    
00082 
00083     public static bool Suits(System.Type type) 
00084     {
00085       if (type.IsArray) {
00086         return true;
00087       }
00088       
00089       return false;
00090     }
00091 
00092     public static void EmitMarshalIn(ILGenerator generator, Type type)
00093     {
00094       if (type.IsByRef) {
00095         generator.Emit(OpCodes.Ldind_Ref);
00096       }
00097     }
00098 
00099     public static void EmitMarshalOut(ILGenerator generator, Type type, bool isReturn) 
00100     {
00101       generator.Emit(OpCodes.Castclass, type);
00102       if (!isReturn) {
00103         generator.Emit(OpCodes.Stind_Ref);
00104       }
00105     }
00106     
00107     public object Get() 
00108     {
00109       throw new ArgumentException("Cannot call Get on an Array without specifying type.");
00110     }
00111 
00112     public object Get(System.Type type)
00113     {
00114       if (type.IsArray)
00115         type = type.GetElementType ();
00116 
00117       if (Arguments.Suits(elementType, type.UnderlyingSystemType)) {
00118         this.val = System.Array.CreateInstance(type.UnderlyingSystemType, elements.Count);
00119         int i = 0;
00120         foreach (DBusType.IDBusType element in elements) {
00121           this.val.SetValue(element.Get(type.UnderlyingSystemType), i++);
00122         }       
00123       } else {
00124         throw new ArgumentException("Cannot cast DBus.Type.Array to type '" + type.ToString() + "'");
00125       }
00126         
00127         return this.val;
00128     }    
00129 
00130     [DllImport("dbus-1")]
00131     private extern static bool dbus_message_iter_open_container (IntPtr iter,
00132                                                                  int containerType,
00133                                                                  string elementType,
00134                                                                  IntPtr subIter);
00135 
00136     [DllImport("dbus-1")]
00137     private extern static bool dbus_message_iter_close_container (IntPtr iter,
00138                                                                   IntPtr subIter);
00139  
00140     [DllImport("dbus-1")]
00141     private extern static int dbus_message_iter_get_element_type(IntPtr iter);
00142 
00143     [DllImport("dbus-1")]
00144     private extern static int dbus_message_iter_get_arg_type(IntPtr iter);
00145 
00146     [DllImport("dbus-1")]
00147     private extern static void dbus_message_iter_recurse(IntPtr iter, IntPtr subIter);
00148 
00149     [DllImport("dbus-1")]
00150     private extern static bool dbus_message_iter_next(IntPtr iter);
00151 
00152     [DllImport("dbus-1")]
00153     private extern static bool dbus_message_iter_has_next (IntPtr iter);
00154   }
00155 }

Generated on Tue Sep 13 01:28:06 2005 for D-BUS by  doxygen 1.4.4