Skip to content
This repository was archived by the owner on Nov 8, 2022. It is now read-only.

Commit 76d8b47

Browse files
committed
proxy: Property get/set via CLR properties
1 parent b288288 commit 76d8b47

File tree

4 files changed

+334
-10
lines changed

4 files changed

+334
-10
lines changed

src/BusObject.cs

+23
Original file line numberDiff line numberDiff line change
@@ -173,6 +173,29 @@ public MessageReader SendMethodCall (string iface, string member, string inSigSt
173173
return retVal;
174174
}
175175

176+
public object SendPropertyGet (string iface, string property)
177+
{
178+
Exception exception;
179+
MessageWriter writer = new MessageWriter ();
180+
writer.Write (iface);
181+
writer.Write (property);
182+
183+
MessageReader reader = SendMethodCall ("org.freedesktop.DBus.Properties", "Get", "ss", writer, typeof(object), out exception);
184+
185+
return reader.ReadValue ();
186+
}
187+
188+
public void SendPropertySet (string iface, string property, object value)
189+
{
190+
Exception exception;
191+
MessageWriter writer = new MessageWriter ();
192+
writer.Write (iface);
193+
writer.Write (property);
194+
writer.Write (typeof(object), value);
195+
196+
SendMethodCall ("org.freedesktop.DBus.Properties", "Set", "ssv", writer, typeof(void), out exception);
197+
}
198+
176199
public void Invoke (MethodBase methodBase, string methodName, object[] inArgs, out object[] outArgs, out object retVal, out Exception exception)
177200
{
178201
Invoke (methodBase, methodName, inArgs, null, out outArgs, out retVal, out exception);

src/ExportObject.cs

+119
Original file line numberDiff line numberDiff line change
@@ -74,13 +74,43 @@ internal static MethodCaller GetMCaller (MethodInfo mi)
7474
return mCaller;
7575
}
7676

77+
internal static MethodCaller GetPropertyCaller(PropertyInfo pi)
78+
{
79+
MethodInfo mi = pi.GetMethod;
80+
MethodCaller mCaller;
81+
if (!mCallers.TryGetValue(mi, out mCaller))
82+
{
83+
mCaller = TypeImplementer.GenGetCall (pi);
84+
mCallers[mi] = mCaller;
85+
}
86+
return mCaller;
87+
}
88+
89+
internal static MethodCaller SetPropertyCaller(PropertyInfo pi)
90+
{
91+
MethodInfo mi = pi.SetMethod;
92+
MethodCaller mCaller;
93+
if (!mCallers.TryGetValue(mi, out mCaller))
94+
{
95+
mCaller = TypeImplementer.GenSetCall (pi);
96+
mCallers[mi] = mCaller;
97+
}
98+
return mCaller;
99+
}
100+
77101
public static ExportObject CreateExportObject (Connection conn, ObjectPath object_path, object obj)
78102
{
79103
return new ExportObject (conn, object_path, obj);
80104
}
81105

82106
public virtual void HandleMethodCall (MessageContainer method_call)
83107
{
108+
if (method_call.Interface == "org.freedesktop.DBus.Properties")
109+
{
110+
HandlePropertyCall (method_call);
111+
return;
112+
}
113+
84114
MethodInfo mi;
85115
if (!methodInfoCache.TryGetValue (method_call.Member, out mi))
86116
methodInfoCache[method_call.Member] = mi = Mapper.GetMethod (Object.GetType (), method_call);
@@ -148,6 +178,95 @@ public virtual void HandleMethodCall (MessageContainer method_call)
148178
}
149179
}
150180

181+
private void HandlePropertyCall(MessageContainer method_call)
182+
{
183+
Message msg = method_call.Message;
184+
MessageReader msgReader = new MessageReader (msg);
185+
MessageWriter retWriter = new MessageWriter ();
186+
187+
object[] args = MessageHelper.GetDynamicValues (msg);
188+
189+
string face = (string)args[0];
190+
191+
if ("GetAll" == method_call.Member) {
192+
conn.MaybeSendUnknownMethodError (method_call);
193+
return;
194+
}
195+
196+
string name = (string)args[1];
197+
198+
PropertyInfo pi = Object.GetType ().GetProperty (name);
199+
200+
if (null == pi)
201+
{
202+
conn.MaybeSendUnknownMethodError (method_call);
203+
return;
204+
}
205+
206+
MethodCaller pc = null;
207+
MethodInfo mi = null;
208+
Signature outSig, inSig = method_call.Signature;
209+
210+
switch (method_call.Member) {
211+
case "Set":
212+
mi = pi.SetMethod;
213+
pc = SetPropertyCaller (pi);
214+
outSig = Signature.Empty;
215+
break;
216+
case "Get":
217+
mi = pi.GetMethod;
218+
pc = GetPropertyCaller (pi);
219+
outSig = Signature.GetSig (mi.ReturnType);
220+
break;
221+
default:
222+
conn.MaybeSendUnknownMethodError (method_call);
223+
return;
224+
}
225+
226+
Exception raisedException = null;
227+
try {
228+
pc (Object, msgReader, msg, retWriter, null);
229+
} catch (Exception e) {
230+
raisedException = e;
231+
}
232+
233+
Message replyMsg;
234+
235+
if (raisedException == null)
236+
{
237+
MessageContainer method_return = new MessageContainer
238+
{
239+
Type = MessageType.MethodReturn,
240+
ReplySerial = msg.Header.Serial
241+
};
242+
replyMsg = method_return.Message;
243+
replyMsg.AttachBodyTo (retWriter);
244+
replyMsg.Signature = outSig;
245+
}
246+
else {
247+
// BusException allows precisely formatted Error messages.
248+
BusException busException = raisedException as BusException;
249+
if (busException != null)
250+
replyMsg = method_call.CreateError (busException.ErrorName, busException.ErrorMessage);
251+
else if (raisedException is ArgumentException && raisedException.TargetSite.Name == mi.Name)
252+
{
253+
// Name match trick above is a hack since we don't have the resolved MethodInfo.
254+
ArgumentException argException = (ArgumentException)raisedException;
255+
using (System.IO.StringReader sr = new System.IO.StringReader (argException.Message))
256+
{
257+
replyMsg = method_call.CreateError ("org.freedesktop.DBus.Error.InvalidArgs", sr.ReadLine());
258+
}
259+
}
260+
else
261+
replyMsg = method_call.CreateError (Mapper.GetInterfaceName(raisedException.GetType()), raisedException.Message);
262+
}
263+
264+
if (method_call.Sender != null)
265+
replyMsg.Header[FieldCode.Destination] = method_call.Sender;
266+
267+
conn.Send (replyMsg);
268+
}
269+
151270
public object Object {
152271
get;
153272
private set;

src/Protocol/MessageReader.cs

+5
Original file line numberDiff line numberDiff line change
@@ -121,6 +121,11 @@ public object ReadValue (Type type)
121121
}
122122
}
123123

124+
public object ReadValue()
125+
{
126+
return ReadValue (message.Signature);
127+
}
128+
124129
public object ReadValue (DType dtype)
125130
{
126131
switch (dtype)

0 commit comments

Comments
 (0)