@@ -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 ;
0 commit comments