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 Custom : IDBusType
00013 {
00014 public const char Code = 'c';
00015 private DBus.Custom val;
00016
00017 private Custom()
00018 {
00019 }
00020
00021 public Custom(DBus.Custom val, Service service)
00022 {
00023 this.val = val;
00024 }
00025
00026 public Custom(IntPtr iter, Service service)
00027 {
00028 string name;
00029 IntPtr value;
00030 int len;
00031
00032 if (!dbus_message_iter_get_custom(iter, out name, out value, out len)) {
00033 throw new ApplicationException("Failed to get CUSTOM argument.");
00034 }
00035
00036 this.val.Name = name;
00037 this.val.Data = new byte[len];
00038 Marshal.Copy(value, this.val.Data, 0, len);
00039 }
00040
00041 public void Append(IntPtr iter)
00042 {
00043 IntPtr data = Marshal.AllocCoTaskMem(this.val.Data.Length);
00044 try {
00045 Marshal.Copy(this.val.Data, 0, data, this.val.Data.Length);
00046 if (!dbus_message_iter_append_custom(iter, this.val.Name, data, this.val.Data.Length)) {
00047 throw new ApplicationException("Failed to append CUSTOM argument:" + val);
00048 }
00049 } finally {
00050 Marshal.FreeCoTaskMem(data);
00051 }
00052 }
00053
00054 public static bool Suits(System.Type type)
00055 {
00056 switch (type.ToString()) {
00057 case "DBus.Custom":
00058 case "DBus.Custom&":
00059 return true;
00060 }
00061
00062 return false;
00063 }
00064
00065 public static void EmitMarshalIn(ILGenerator generator, Type type)
00066 {
00067 if (type.IsByRef) {
00068 generator.Emit(OpCodes.Ldobj, type);
00069 }
00070 }
00071
00072 public static void EmitMarshalOut(ILGenerator generator, Type type, bool isReturn)
00073 {
00074 generator.Emit(OpCodes.Unbox, type);
00075 generator.Emit(OpCodes.Ldobj, type);
00076 if (!isReturn) {
00077 generator.Emit(OpCodes.Stobj, type);
00078 }
00079 }
00080
00081 public object Get()
00082 {
00083 return this.val;
00084 }
00085
00086 public object Get(System.Type type)
00087 {
00088 switch (type.ToString()) {
00089 case "DBus.Custom":
00090 case "DBus.Custom&":
00091 return this.val;
00092 default:
00093 throw new ArgumentException("Cannot cast DBus.Type.Custom to type '" + type.ToString() + "'");
00094 }
00095 }
00096
00097 [DllImport("dbus-1")]
00098 private extern static bool dbus_message_iter_get_custom(IntPtr iter,
00099 out string name,
00100 out IntPtr value,
00101 out int len);
00102
00103 [DllImport("dbus-1")]
00104 private extern static bool dbus_message_iter_append_custom(IntPtr iter,
00105 string name,
00106 IntPtr data,
00107 int len);
00108 }
00109 }