Main Page | Modules | Class Hierarchy | Data Structures | Directories | File List | 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().UnderlyingSystemType);
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;
00039       bool notEmpty = dbus_message_iter_init_array_iterator(iter, arrayIter, out elementTypeCode);
00040       this.elementType = (Type) Arguments.DBusTypes[(char) elementTypeCode];
00041 
00042       elements = new ArrayList();
00043 
00044       if (notEmpty) {
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_append_array(iter,
00062                                           arrayIter,
00063                                           (int) Arguments.GetCode(this.elementType))) {
00064         throw new ApplicationException("Failed to append INT32 argument:" + val);
00065       }
00066 
00067       foreach (object element in this.val) {
00068         object [] pars = new Object[2];
00069         pars[0] = element;
00070         pars[1] = this.service;
00071         DBusType.IDBusType dbusType = (DBusType.IDBusType) Activator.CreateInstance(elementType, pars);
00072         dbusType.Append(arrayIter);
00073       }
00074 
00075       Marshal.FreeCoTaskMem(arrayIter);
00076     }    
00077 
00078     public static bool Suits(System.Type type) 
00079     {
00080       if (type.IsArray) {
00081         return true;
00082       }
00083       
00084       return false;
00085     }
00086 
00087     public static void EmitMarshalIn(ILGenerator generator, Type type)
00088     {
00089       if (type.IsByRef) {
00090         generator.Emit(OpCodes.Ldind_Ref);
00091       }
00092     }
00093 
00094     public static void EmitMarshalOut(ILGenerator generator, Type type, bool isReturn) 
00095     {
00096       generator.Emit(OpCodes.Castclass, type);
00097       if (!isReturn) {
00098         generator.Emit(OpCodes.Stind_Ref);
00099       }
00100     }
00101     
00102     public object Get() 
00103     {
00104       throw new ArgumentException("Cannot call Get on an Array without specifying type.");
00105     }
00106 
00107     public object Get(System.Type type)
00108     {
00109       if (type.IsArray)
00110         type = type.GetElementType ();
00111 
00112       if (Arguments.Suits(elementType, type.UnderlyingSystemType)) {
00113         this.val = System.Array.CreateInstance(type.UnderlyingSystemType, elements.Count);
00114         int i = 0;
00115         foreach (DBusType.IDBusType element in elements) {
00116           this.val.SetValue(element.Get(type.UnderlyingSystemType), i++);
00117         }       
00118       } else {
00119         throw new ArgumentException("Cannot cast DBus.Type.Array to type '" + type.ToString() + "'");
00120       }
00121         
00122         return this.val;
00123     }    
00124 
00125     [DllImport("dbus-1")]
00126     private extern static bool dbus_message_iter_init_array_iterator(IntPtr iter,
00127                                                                      IntPtr arrayIter,
00128                                                                      out int elementType);
00129  
00130     [DllImport("dbus-1")]
00131     private extern static bool dbus_message_iter_append_array(IntPtr iter, 
00132                                                               IntPtr arrayIter,
00133                                                               int elementType);
00134 
00135     [DllImport("dbus-1")]
00136     private extern static bool dbus_message_iter_has_next(IntPtr iter);
00137 
00138     [DllImport("dbus-1")]
00139     private extern static bool dbus_message_iter_next(IntPtr iter);
00140   }
00141 }

Generated on Tue Mar 22 23:25:48 2005 for D-BUS by  doxygen 1.4.1