1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105
|
// Copyright 2006 Alp Toker <alp@atoker.com>
// This software is made available under the MIT License
// See COPYING for details
using System;
using System.Reflection;
using System.Reflection.Emit;
using org.freedesktop.DBus;
namespace NDesk.DBus
{
//TODO: perhaps ExportObject should not derive from BusObject
internal class ExportObject : BusObject //, Peer
{
public readonly object obj;
public ExportObject (Connection conn, ObjectPath object_path, object obj) : base (conn, null, object_path)
{
this.obj = obj;
}
//maybe add checks to make sure this is not called more than once
//it's a bit silly as a property
public bool Registered
{
set {
Type type = obj.GetType ();
foreach (MemberInfo mi in Mapper.GetPublicMembers (type)) {
EventInfo ei = mi as EventInfo;
if (ei == null)
continue;
Delegate dlg = GetHookupDelegate (ei);
if (value)
ei.AddEventHandler (obj, dlg);
else
ei.RemoveEventHandler (obj, dlg);
}
}
}
public void HandleMethodCall (MethodCall method_call)
{
Type type = obj.GetType ();
//object retObj = type.InvokeMember (msg.Member, BindingFlags.InvokeMethod, null, obj, MessageHelper.GetDynamicValues (msg));
//TODO: there is no member name mapping for properties etc. yet
MethodInfo mi = Mapper.GetMethod (type, method_call);
if (mi == null) {
conn.MaybeSendUnknownMethodError (method_call);
return;
}
object retObj = null;
object[] parmValues = MessageHelper.GetDynamicValues (method_call.message, mi.GetParameters ());
try {
retObj = mi.Invoke (obj, parmValues);
} catch (TargetInvocationException e) {
if (!method_call.message.ReplyExpected)
return;
Exception ie = e.InnerException;
//TODO: complete exception sending support
Error error = new Error (Mapper.GetInterfaceName (ie.GetType ()), method_call.message.Header.Serial);
error.message.Signature = new Signature (DType.String);
MessageWriter writer = new MessageWriter (Connection.NativeEndianness);
writer.connection = conn;
writer.Write (ie.Message);
error.message.Body = writer.ToArray ();
//TODO: we should be more strict here, but this fallback was added as a quick fix for p2p
if (method_call.Sender != null)
error.message.Header.Fields[FieldCode.Destination] = method_call.Sender;
conn.Send (error.message);
return;
}
if (method_call.message.ReplyExpected) {
Message reply = MessageHelper.ConstructDynamicReply (method_call, mi, retObj, parmValues);
conn.Send (reply);
}
}
/*
public void Ping ()
{
}
public string GetMachineId ()
{
//TODO: implement this
return String.Empty;
}
*/
}
}
|