00001 using System;
00002 using System.Runtime.InteropServices;
00003 using System.Reflection.Emit;
00004
00005 using DBus;
00006
00007 namespace DBus.DBusType
00008 {
00012 public class ObjectPath : IDBusType
00013 {
00014 public const char Code = 'o';
00015 private string path = null;
00016 private object val = null;
00017 private Service service = null;
00018
00019 private ObjectPath()
00020 {
00021 }
00022
00023 public ObjectPath(object val, Service service)
00024 {
00025 this.val = val;
00026 this.service = service;
00027 }
00028
00029 public ObjectPath(IntPtr iter, Service service)
00030 {
00031 IntPtr raw_str = dbus_message_iter_get_object_path (iter);
00032 this.path = Marshal.PtrToStringAnsi (raw_str);
00033 dbus_free (raw_str);
00034
00035 this.service = service;
00036 }
00037
00038 private string Path
00039 {
00040 get {
00041 if (this.path == null && this.val != null) {
00042 Handler handler = this.service.GetHandler(this.val);
00043 this.path = handler.Path;
00044 }
00045
00046 return this.path;
00047 }
00048 }
00049
00050 public void Append(IntPtr iter)
00051 {
00052 IntPtr raw_str = Marshal.StringToHGlobalAnsi (Path);
00053
00054 bool success = dbus_message_iter_append_object_path (iter, raw_str);
00055 Marshal.FreeHGlobal (raw_str);
00056
00057 if (!success)
00058 throw new ApplicationException("Failed to append OBJECT_PATH argument:" + val);
00059 }
00060
00061 public static bool Suits(System.Type type)
00062 {
00063 object[] attributes = type.GetCustomAttributes(typeof(InterfaceAttribute), false);
00064 if (attributes.Length == 1) {
00065 return true;
00066 } else {
00067 return false;
00068 }
00069 }
00070
00071 public static void EmitMarshalIn(ILGenerator generator, Type type)
00072 {
00073 if (type.IsByRef) {
00074 generator.Emit(OpCodes.Ldind_Ref);
00075 }
00076 }
00077
00078 public static void EmitMarshalOut(ILGenerator generator, Type type, bool isReturn)
00079 {
00080 generator.Emit(OpCodes.Castclass, type);
00081 if (!isReturn) {
00082 generator.Emit(OpCodes.Stind_Ref);
00083 }
00084 }
00085
00086 public object Get()
00087 {
00088 throw new ArgumentException("Cannot call Get on an ObjectPath without specifying type.");
00089 }
00090
00091 public object Get(System.Type type)
00092 {
00093 try {
00094 return this.service.GetObject(type, Path);
00095 } catch(Exception ex) {
00096 throw new ArgumentException("Cannot cast object pointed to by Object Path to type '" + type.ToString() + "': " + ex);
00097 }
00098 }
00099
00100 [DllImport("dbus-1")]
00101 private extern static IntPtr dbus_message_iter_get_object_path(IntPtr iter);
00102
00103 [DllImport("dbus-1")]
00104 private extern static bool dbus_message_iter_append_object_path(IntPtr iter, IntPtr path);
00105
00106 [DllImport("dbus-1")]
00107 private extern static void dbus_free (IntPtr raw);
00108 }
00109 }