~ubuntu-branches/ubuntu/gutsy/tomboy/gutsy-updates

« back to all changes in this revision

Viewing changes to Tomboy/dbus-sharp/ProxyBuilder.cs

  • Committer: Bazaar Package Importer
  • Author(s): Sebastian Dröge
  • Date: 2006-11-22 19:22:17 UTC
  • mfrom: (1.1.8 upstream)
  • Revision ID: james.westby@ubuntu.com-20061122192217-odnb17d1ib22okof
Tags: 0.5.1-0ubuntu1
* New upstream release:
  + New Managed D-Bus/DBusSharp (Sebastian Dröge)
  + Additional search interface improvements
  + More secure wrapper script to launch Tomboy.exe
  + Fix panel and TrayIcon resizing
  + Fix 1x1 pixel TrayIcon
  + Removed old tintin image
* debian/control:
  + Update build dependencies
* debian/patches/01-dbus0.9.patch,
  debian/patches/50_tintin.patch,
  debian/patches/51_tomboy-dllmap.patch,
  debian/patches/52_external-dbus-sharp.patch,
  debian/patches/53_tomboy-tray-icon.patch:
  + Dropped, merged upstream
* debian/rules,
  debian/tomboy.desktop:
  + Use upstream's desktop file again after it was fixed now
* debian/rules:
  + DBus service file path workaround removed, it's fixed upstream

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
namespace DBus
2
 
{
3
 
  using System;
4
 
  using System.Runtime.InteropServices;
5
 
  using System.Diagnostics;
6
 
  using System.Collections;
7
 
  using System.Threading;
8
 
  using System.Reflection;
9
 
  using System.Reflection.Emit;
10
 
 
11
 
  internal class ProxyBuilder
12
 
  {
13
 
    private Service service= null;
14
 
    private string pathName = null;
15
 
    private Type type = null;
16
 
    private Introspector introspector = null;
17
 
    
18
 
    private static MethodInfo Service_NameMI = typeof(Service).GetMethod("get_Name", 
19
 
                                                                            new Type[0]);
20
 
    private static MethodInfo Service_ConnectionMI = typeof(Service).GetMethod("get_Connection",
21
 
                                                                                  new Type[0]);
22
 
    private static MethodInfo Service_AddSignalCalledMI = typeof(Service).GetMethod("add_SignalCalled",
23
 
                                                                                    new Type[] {typeof(Service.SignalCalledHandler)});
24
 
    private static MethodInfo Service_RemoveSignalCalledMI = typeof(Service).GetMethod("remove_SignalCalled",
25
 
                                                                                    new Type[] {typeof(Service.SignalCalledHandler)});                                                                              
26
 
    private static MethodInfo Signal_PathNameMI = typeof(Signal).GetMethod("get_PathName",
27
 
                                                                           new Type[0]);
28
 
    private static MethodInfo Message_ArgumentsMI = typeof(Message).GetMethod("get_Arguments",
29
 
                                                                                 new Type[0]);
30
 
    private static MethodInfo Message_KeyMI = typeof(Message).GetMethod("get_Key",
31
 
                                                                        new Type[0]);
32
 
    private static MethodInfo Arguments_InitAppendingMI = typeof(Arguments).GetMethod("InitAppending",
33
 
                                                                                          new Type[0]);
34
 
    private static MethodInfo Arguments_AppendMI = typeof(Arguments).GetMethod("Append",
35
 
                                                                                  new Type[] {typeof(DBusType.IDBusType)});
36
 
    private static MethodInfo Message_SendWithReplyAndBlockMI = typeof(Message).GetMethod("SendWithReplyAndBlock",
37
 
                                                                                             new Type[0]);
38
 
    private static MethodInfo Message_SendMI = typeof(Message).GetMethod("Send",
39
 
                                                                         new Type[0]);
40
 
    private static MethodInfo Message_DisposeMI = typeof(Message).GetMethod("Dispose",
41
 
                                                                            new Type[0]);
42
 
    private static MethodInfo Arguments_GetEnumeratorMI = typeof(Arguments).GetMethod("GetEnumerator",
43
 
                                                                                          new Type[0]);
44
 
    private static MethodInfo IEnumerator_MoveNextMI = typeof(System.Collections.IEnumerator).GetMethod("MoveNext",
45
 
                                                                                                        new Type[0]);
46
 
    private static MethodInfo IEnumerator_CurrentMI = typeof(System.Collections.IEnumerator).GetMethod("get_Current",
47
 
                                                                                                       new Type[0]);
48
 
    private static MethodInfo Type_GetTypeFromHandleMI = typeof(System.Type).GetMethod("GetTypeFromHandle",
49
 
                                                                                       new Type[] {typeof(System.RuntimeTypeHandle)});
50
 
    private static MethodInfo IDBusType_GetMI = typeof(DBusType.IDBusType).GetMethod("Get",
51
 
                                                                                     new Type[] {typeof(System.Type)});
52
 
    private static ConstructorInfo MethodCall_C = typeof(MethodCall).GetConstructor(new Type[] {typeof(Service),
53
 
                                                                                                typeof(string),
54
 
                                                                                                typeof(string),
55
 
                                                                                                typeof(string)});
56
 
    private static ConstructorInfo Signal_C = typeof(Signal).GetConstructor(new Type[] {typeof(Service),
57
 
                                                                                        typeof(string),
58
 
                                                                                        typeof(string),
59
 
                                                                                        typeof(string)});
60
 
    private static ConstructorInfo Service_SignalCalledHandlerC = typeof(Service.SignalCalledHandler).GetConstructor(new Type[] {typeof(object),
61
 
                                                                                                                                 typeof(System.IntPtr)});
62
 
    private static MethodInfo String_opEqualityMI = typeof(System.String).GetMethod("op_Equality",
63
 
                                                                                    new Type[] {typeof(string),
64
 
                                                                                                typeof(string)});                                                                                                            
65
 
    private static MethodInfo MulticastDelegate_opInequalityMI = typeof(System.MulticastDelegate).GetMethod("op_Inequality",
66
 
                                                                                    new Type[] {typeof(System.MulticastDelegate),
67
 
                                                                                                typeof(System.MulticastDelegate)});
68
 
    
69
 
 
70
 
    public ProxyBuilder(Service service, Type type, string pathName)
71
 
    {
72
 
      this.service = service;
73
 
      this.pathName = pathName;
74
 
      this.type = type;
75
 
      this.introspector = Introspector.GetIntrospector(type);
76
 
    }
77
 
 
78
 
    private MethodInfo BuildSignalCalled(ref TypeBuilder typeB, FieldInfo serviceF, FieldInfo pathF)
79
 
    {
80
 
      Type[] parTypes = {typeof(Signal)};
81
 
      MethodBuilder methodBuilder = typeB.DefineMethod("Service_SignalCalled",
82
 
                                                       MethodAttributes.Private |
83
 
                                                       MethodAttributes.HideBySig,
84
 
                                                       typeof(void),
85
 
                                                       parTypes);
86
 
      
87
 
      ILGenerator generator = methodBuilder.GetILGenerator();
88
 
 
89
 
      LocalBuilder enumeratorL = generator.DeclareLocal(typeof(System.Collections.IEnumerator));
90
 
      enumeratorL.SetLocalSymInfo("enumerator");
91
 
 
92
 
      Label wrongPath = generator.DefineLabel();
93
 
      //generator.EmitWriteLine("if (signal.PathName == pathName) {");
94
 
      generator.Emit(OpCodes.Ldarg_1);
95
 
      generator.EmitCall(OpCodes.Callvirt, Signal_PathNameMI, null);
96
 
      generator.Emit(OpCodes.Ldarg_0);
97
 
      generator.Emit(OpCodes.Ldfld, pathF);
98
 
      generator.EmitCall(OpCodes.Call, String_opEqualityMI, null);
99
 
      generator.Emit(OpCodes.Brfalse, wrongPath);
100
 
 
101
 
      int localOffset = 1;
102
 
 
103
 
      foreach (DictionaryEntry interfaceEntry in this.introspector.InterfaceProxies) {
104
 
        InterfaceProxy interfaceProxy = (InterfaceProxy) interfaceEntry.Value;
105
 
        foreach (DictionaryEntry signalEntry in interfaceProxy.Signals) {
106
 
          EventInfo eventE = (EventInfo) signalEntry.Value;
107
 
          // This is really cheeky since we need to grab the event as a private field.
108
 
          FieldInfo eventF = this.type.GetField(eventE.Name,
109
 
                                                BindingFlags.NonPublic|
110
 
                                                BindingFlags.Instance);
111
 
 
112
 
          MethodInfo eventHandler_InvokeMI = eventE.EventHandlerType.GetMethod("Invoke");
113
 
 
114
 
          ParameterInfo[] pars = eventHandler_InvokeMI.GetParameters();
115
 
          parTypes = new Type[pars.Length];
116
 
          for (int parN = 0; parN < pars.Length; parN++) {
117
 
            parTypes[parN] = pars[parN].ParameterType;
118
 
            LocalBuilder parmL = generator.DeclareLocal(parTypes[parN]);
119
 
            parmL.SetLocalSymInfo(pars[parN].Name);
120
 
          }
121
 
          
122
 
          Label skip = generator.DefineLabel();      
123
 
          //generator.EmitWriteLine("  if (SelectedIndexChanged != null) {");
124
 
          generator.Emit(OpCodes.Ldarg_0);
125
 
          generator.Emit(OpCodes.Ldfld, eventF);
126
 
          generator.Emit(OpCodes.Ldnull);
127
 
          generator.EmitCall(OpCodes.Call, MulticastDelegate_opInequalityMI, null);
128
 
          generator.Emit(OpCodes.Brfalse, skip);
129
 
          
130
 
          //generator.EmitWriteLine("    if (signal.Key == 'la i')");
131
 
          generator.Emit(OpCodes.Ldarg_1);
132
 
          generator.EmitCall(OpCodes.Callvirt, Message_KeyMI, null);
133
 
          generator.Emit(OpCodes.Ldstr, eventE.Name + " " + InterfaceProxy.GetSignature(eventHandler_InvokeMI));
134
 
          generator.EmitCall(OpCodes.Call, String_opEqualityMI, null);
135
 
          generator.Emit(OpCodes.Brfalse, skip);
136
 
 
137
 
          //generator.EmitWriteLine("IEnumerator enumerator = signal.Arguments.GetEnumerator()");
138
 
          generator.Emit(OpCodes.Ldarg_1);
139
 
          generator.EmitCall(OpCodes.Callvirt, Message_ArgumentsMI, null);
140
 
          generator.EmitCall(OpCodes.Callvirt, Arguments_GetEnumeratorMI, null);
141
 
          generator.Emit(OpCodes.Stloc_0);
142
 
          
143
 
          for (int parN = 0; parN < pars.Length; parN++) {
144
 
            ParameterInfo par = pars[parN];
145
 
            if (!par.IsOut) {
146
 
              EmitSignalIn(generator, par.ParameterType, parN + localOffset, serviceF);
147
 
            }
148
 
          }
149
 
          
150
 
          //generator.EmitWriteLine("    SelectedIndexChanged(selectedIndex)");
151
 
          generator.Emit(OpCodes.Ldarg_0);
152
 
          generator.Emit(OpCodes.Ldfld, eventF);
153
 
          for (int parN = 0; parN < pars.Length; parN++) {
154
 
            generator.Emit(OpCodes.Ldloc_S, parN + localOffset);
155
 
          }
156
 
          
157
 
          generator.EmitCall(OpCodes.Callvirt, eventHandler_InvokeMI, null);
158
 
          
159
 
          generator.MarkLabel(skip);
160
 
          //generator.EmitWriteLine("  }");
161
 
          
162
 
          localOffset += pars.Length;
163
 
        }
164
 
      }
165
 
 
166
 
      generator.MarkLabel(wrongPath);
167
 
      //generator.EmitWriteLine("}");
168
 
 
169
 
      //generator.EmitWriteLine("return");
170
 
      generator.Emit(OpCodes.Ret);
171
 
 
172
 
      return methodBuilder;
173
 
    }
174
 
    
175
 
    private void BuildSignalHandler(EventInfo eventE, 
176
 
                                    InterfaceProxy interfaceProxy,
177
 
                                    ref TypeBuilder typeB, 
178
 
                                    FieldInfo serviceF,
179
 
                                    FieldInfo pathF)
180
 
    {
181
 
      MethodInfo eventHandler_InvokeMI = eventE.EventHandlerType.GetMethod("Invoke");
182
 
      ParameterInfo[] pars = eventHandler_InvokeMI.GetParameters();
183
 
      Type[] parTypes = new Type[pars.Length];
184
 
      for (int parN = 0; parN < pars.Length; parN++) {
185
 
        parTypes[parN] = pars[parN].ParameterType;
186
 
      }
187
 
 
188
 
      // Generate the code
189
 
      MethodBuilder methodBuilder = typeB.DefineMethod("Proxy_" + eventE.Name, 
190
 
                                                       MethodAttributes.Public |
191
 
                                                       MethodAttributes.HideBySig |
192
 
                                                       MethodAttributes.Virtual, 
193
 
                                                       typeof(void),
194
 
                                                       parTypes);
195
 
      ILGenerator generator = methodBuilder.GetILGenerator();
196
 
 
197
 
      for (int parN = 0; parN < pars.Length; parN++) {
198
 
        methodBuilder.DefineParameter(parN + 1, pars[parN].Attributes, pars[parN].Name);
199
 
      }
200
 
 
201
 
      // Generate the locals
202
 
      LocalBuilder methodCallL = generator.DeclareLocal(typeof(MethodCall));
203
 
      methodCallL.SetLocalSymInfo("signal");
204
 
 
205
 
      //generator.EmitWriteLine("Signal signal = new Signal(...)");
206
 
      generator.Emit(OpCodes.Ldsfld, serviceF);
207
 
      generator.Emit(OpCodes.Ldarg_0);
208
 
      generator.Emit(OpCodes.Ldfld, pathF);
209
 
      generator.Emit(OpCodes.Ldstr, interfaceProxy.InterfaceName);
210
 
      generator.Emit(OpCodes.Ldstr, eventE.Name);
211
 
      generator.Emit(OpCodes.Newobj, Signal_C);
212
 
      generator.Emit(OpCodes.Stloc_0);
213
 
 
214
 
      //generator.EmitWriteLine("signal.Arguments.InitAppending()");
215
 
      generator.Emit(OpCodes.Ldloc_0);
216
 
      generator.EmitCall(OpCodes.Callvirt, Message_ArgumentsMI, null);
217
 
      generator.EmitCall(OpCodes.Callvirt, Arguments_InitAppendingMI, null);
218
 
 
219
 
      for (int parN = 0; parN < pars.Length; parN++) {
220
 
        ParameterInfo par = pars[parN];
221
 
        if (!par.IsOut) {
222
 
          EmitIn(generator, par.ParameterType, parN, serviceF);
223
 
        }
224
 
      }
225
 
      
226
 
      //generator.EmitWriteLine("signal.Send()");
227
 
      generator.Emit(OpCodes.Ldloc_0);
228
 
      generator.EmitCall(OpCodes.Callvirt, Message_SendMI, null); 
229
 
 
230
 
      //generator.EmitWriteLine("signal.Dispose()");
231
 
      generator.Emit(OpCodes.Ldloc_0);
232
 
      generator.EmitCall(OpCodes.Callvirt, Message_DisposeMI, null);
233
 
 
234
 
      //generator.EmitWriteLine("return");
235
 
      generator.Emit(OpCodes.Ret);
236
 
    }
237
 
 
238
 
    private void BuildMethod(MethodInfo method, 
239
 
                             InterfaceProxy interfaceProxy,
240
 
                             ref TypeBuilder typeB, 
241
 
                             FieldInfo serviceF,
242
 
                             FieldInfo pathF)
243
 
    {
244
 
      ParameterInfo[] pars = method.GetParameters();
245
 
      Type[] parTypes = new Type[pars.Length];
246
 
      for (int parN = 0; parN < pars.Length; parN++) {
247
 
        parTypes[parN] = pars[parN].ParameterType;
248
 
      }
249
 
 
250
 
      // Generate the code
251
 
      MethodBuilder methodBuilder = typeB.DefineMethod(method.Name, 
252
 
                                                       MethodAttributes.Public |
253
 
                                                       MethodAttributes.HideBySig |
254
 
                                                       MethodAttributes.Virtual, 
255
 
                                                       method.ReturnType, 
256
 
                                                       parTypes);
257
 
      ILGenerator generator = methodBuilder.GetILGenerator();
258
 
 
259
 
      for (int parN = 0; parN < pars.Length; parN++) {
260
 
        methodBuilder.DefineParameter(parN + 1, pars[parN].Attributes, pars[parN].Name);
261
 
      }
262
 
 
263
 
      // Generate the locals
264
 
      LocalBuilder methodCallL = generator.DeclareLocal(typeof(MethodCall));
265
 
      methodCallL.SetLocalSymInfo("methodCall");
266
 
      LocalBuilder replyL = generator.DeclareLocal(typeof(MethodReturn));
267
 
      replyL.SetLocalSymInfo("reply");
268
 
      LocalBuilder enumeratorL = generator.DeclareLocal(typeof(System.Collections.IEnumerator));
269
 
      enumeratorL.SetLocalSymInfo("enumerator");
270
 
 
271
 
      if (method.ReturnType != typeof(void)) {
272
 
        LocalBuilder retvalL = generator.DeclareLocal(method.ReturnType);
273
 
        retvalL.SetLocalSymInfo("retval");
274
 
      }
275
 
 
276
 
      //generator.EmitWriteLine("MethodCall methodCall = new MethodCall(...)");
277
 
      generator.Emit(OpCodes.Ldsfld, serviceF);
278
 
      generator.Emit(OpCodes.Ldarg_0);
279
 
      generator.Emit(OpCodes.Ldfld, pathF);
280
 
      generator.Emit(OpCodes.Ldstr, interfaceProxy.InterfaceName);
281
 
      generator.Emit(OpCodes.Ldstr, method.Name);
282
 
      generator.Emit(OpCodes.Newobj, MethodCall_C);
283
 
      generator.Emit(OpCodes.Stloc_0);
284
 
 
285
 
      //generator.EmitWriteLine("methodCall.Arguments.InitAppending()");
286
 
      generator.Emit(OpCodes.Ldloc_0);
287
 
      generator.EmitCall(OpCodes.Callvirt, Message_ArgumentsMI, null);
288
 
      generator.EmitCall(OpCodes.Callvirt, Arguments_InitAppendingMI, null);
289
 
 
290
 
      for (int parN = 0; parN < pars.Length; parN++) {
291
 
        ParameterInfo par = pars[parN];
292
 
        if (!par.IsOut) {
293
 
          EmitIn(generator, par.ParameterType, parN, serviceF);
294
 
        }
295
 
      }
296
 
      
297
 
      //generator.EmitWriteLine("MethodReturn reply = methodCall.SendWithReplyAndBlock()");
298
 
      generator.Emit(OpCodes.Ldloc_0);
299
 
      generator.EmitCall(OpCodes.Callvirt, Message_SendWithReplyAndBlockMI, null);      
300
 
      generator.Emit(OpCodes.Stloc_1);
301
 
 
302
 
      //generator.EmitWriteLine("IEnumerator enumeartor = reply.Arguments.GetEnumerator()");
303
 
      generator.Emit(OpCodes.Ldloc_1);
304
 
      generator.EmitCall(OpCodes.Callvirt, Message_ArgumentsMI, null);
305
 
      generator.EmitCall(OpCodes.Callvirt, Arguments_GetEnumeratorMI, null);
306
 
      generator.Emit(OpCodes.Stloc_2);
307
 
 
308
 
      // handle the return value
309
 
      if (method.ReturnType != typeof(void)) {
310
 
        EmitOut(generator, method.ReturnType, 0);
311
 
      }
312
 
 
313
 
      for (int parN = 0; parN < pars.Length; parN++) {
314
 
        ParameterInfo par = pars[parN];
315
 
        if (par.IsOut || par.ParameterType.ToString().EndsWith("&")) {
316
 
          EmitOut(generator, par.ParameterType, parN);
317
 
        }
318
 
      }
319
 
 
320
 
      // Clean up after ourselves
321
 
      //generator.EmitWriteLine("methodCall.Dispose()");
322
 
      generator.Emit(OpCodes.Ldloc_0);
323
 
      generator.EmitCall(OpCodes.Callvirt, Message_DisposeMI, null);
324
 
 
325
 
      //generator.EmitWriteLine("reply.Dispose()");
326
 
      generator.Emit(OpCodes.Ldloc_1);
327
 
      generator.EmitCall(OpCodes.Callvirt, Message_DisposeMI, null);
328
 
 
329
 
      if (method.ReturnType != typeof(void)) {
330
 
        generator.Emit(OpCodes.Ldloc_3);
331
 
      }
332
 
      
333
 
      generator.Emit(OpCodes.Ret);
334
 
 
335
 
      // Generate the method
336
 
      typeB.DefineMethodOverride(methodBuilder, method);
337
 
    }
338
 
 
339
 
    private void EmitSignalIn(ILGenerator generator, Type parType, int parN, FieldInfo serviceF)
340
 
    {
341
 
        //generator.EmitWriteLine("enumerator.MoveNext()");
342
 
        generator.Emit(OpCodes.Ldloc_0);
343
 
        generator.EmitCall(OpCodes.Callvirt, IEnumerator_MoveNextMI, null);
344
 
        
345
 
        Type outParType = Arguments.MatchType(parType);
346
 
        //generator.EmitWriteLine("int selectedIndex = (int) ((DBusType.IDBusType) enumerator.Current).Get(typeof(int))");
347
 
        generator.Emit(OpCodes.Pop);
348
 
        generator.Emit(OpCodes.Ldloc_0);
349
 
        generator.EmitCall(OpCodes.Callvirt, IEnumerator_CurrentMI, null);
350
 
        generator.Emit(OpCodes.Castclass, typeof(DBusType.IDBusType));
351
 
        generator.Emit(OpCodes.Ldtoken, parType);
352
 
        generator.EmitCall(OpCodes.Call, Type_GetTypeFromHandleMI, null);
353
 
        generator.EmitCall(OpCodes.Callvirt, IDBusType_GetMI, null);
354
 
        // Call the DBusType EmitMarshalOut to make it emit itself
355
 
        object[] pars = new object[] {generator, parType, true};
356
 
        outParType.InvokeMember("EmitMarshalOut", BindingFlags.Static | BindingFlags.Public | BindingFlags.InvokeMethod, null, null, pars, null);
357
 
        generator.Emit(OpCodes.Stloc_S, parN);
358
 
    }
359
 
    
360
 
 
361
 
    private void EmitIn(ILGenerator generator, Type parType, int parN, FieldInfo serviceF)
362
 
    {
363
 
      Type inParType = Arguments.MatchType(parType);
364
 
      //generator.EmitWriteLine("methodCall.Arguments.Append(...)");
365
 
      generator.Emit(OpCodes.Ldloc_0);
366
 
      generator.EmitCall(OpCodes.Callvirt, Message_ArgumentsMI, null);
367
 
      generator.Emit(OpCodes.Ldarg_S, parN + 1);
368
 
 
369
 
      // Call the DBusType EmitMarshalIn to make it emit itself
370
 
      object[] pars = new object[] {generator, parType};
371
 
      inParType.InvokeMember("EmitMarshalIn", BindingFlags.Static | BindingFlags.Public | BindingFlags.InvokeMethod, null, null, pars, null);
372
 
 
373
 
      generator.Emit(OpCodes.Ldsfld, serviceF);
374
 
      generator.Emit(OpCodes.Newobj, Arguments.GetDBusTypeConstructor(inParType, parType));
375
 
      generator.EmitCall(OpCodes.Callvirt, Arguments_AppendMI, null);
376
 
    }
377
 
 
378
 
    private void EmitOut(ILGenerator generator, Type parType, int parN)
379
 
    {
380
 
      Type outParType = Arguments.MatchType(parType);
381
 
      //generator.EmitWriteLine("enumerator.MoveNext()");
382
 
      generator.Emit(OpCodes.Ldloc_2);
383
 
      generator.EmitCall(OpCodes.Callvirt, IEnumerator_MoveNextMI, null);
384
 
 
385
 
      //generator.EmitWriteLine("return (" + parType + ") ((DBusType.IDBusType) enumerator.Current).Get(typeof(" + parType + "))");
386
 
      generator.Emit(OpCodes.Pop);
387
 
      if (parN > 0) {
388
 
        generator.Emit(OpCodes.Ldarg_S, parN + 1);
389
 
      }
390
 
      
391
 
      generator.Emit(OpCodes.Ldloc_2);
392
 
      generator.EmitCall(OpCodes.Callvirt, IEnumerator_CurrentMI, null);
393
 
      generator.Emit(OpCodes.Castclass, typeof(DBusType.IDBusType));
394
 
      generator.Emit(OpCodes.Ldtoken, parType);
395
 
      generator.EmitCall(OpCodes.Call, Type_GetTypeFromHandleMI, null);
396
 
      generator.EmitCall(OpCodes.Callvirt, IDBusType_GetMI, null);
397
 
 
398
 
      // Call the DBusType EmitMarshalOut to make it emit itself
399
 
      object[] pars = new object[] {generator, parType, parN == 0};
400
 
      outParType.InvokeMember("EmitMarshalOut", BindingFlags.Static | BindingFlags.Public | BindingFlags.InvokeMethod, null, null, pars, null);
401
 
      
402
 
      if (parN == 0) {
403
 
        generator.Emit(OpCodes.Stloc_3);
404
 
      }
405
 
    }
406
 
    
407
 
    public void BuildConstructor(ref TypeBuilder typeB, FieldInfo serviceF, FieldInfo pathF, MethodInfo signalCalledMI, FieldInfo deleF)
408
 
    {
409
 
      Type[] pars = {typeof(Service), typeof(string)};
410
 
      ConstructorBuilder constructor = typeB.DefineConstructor(MethodAttributes.RTSpecialName | 
411
 
                                                               MethodAttributes.Public,
412
 
                                                               CallingConventions.Standard, pars);
413
 
 
414
 
      ILGenerator generator = constructor.GetILGenerator();
415
 
 
416
 
      LocalBuilder handlerL = generator.DeclareLocal (typeof (Service.SignalCalledHandler));
417
 
      handlerL.SetLocalSymInfo ("handler");
418
 
 
419
 
      generator.Emit(OpCodes.Ldarg_0);
420
 
      generator.Emit(OpCodes.Call, this.introspector.Constructor);
421
 
      //generator.EmitWriteLine("service = myService");
422
 
      generator.Emit(OpCodes.Ldarg_1);
423
 
      generator.Emit(OpCodes.Stsfld, serviceF);
424
 
      //generator.EmitWriteLine("this.pathName = pathName");
425
 
      generator.Emit(OpCodes.Ldarg_0);
426
 
      generator.Emit(OpCodes.Ldarg_2);
427
 
      generator.Emit(OpCodes.Stfld, pathF);
428
 
 
429
 
      //generator.EmitWriteLine("handler = new Service.SignalCalledHandler(Service_SignalCalled)");      
430
 
      generator.Emit(OpCodes.Ldarg_1);
431
 
      generator.Emit(OpCodes.Ldarg_0);
432
 
      generator.Emit(OpCodes.Ldftn, signalCalledMI);
433
 
      generator.Emit(OpCodes.Newobj, Service_SignalCalledHandlerC);
434
 
      generator.Emit(OpCodes.Stloc_0);
435
 
 
436
 
      //generator.EmitWriteLine("this.delegate_created = handler");
437
 
      generator.Emit(OpCodes.Ldarg_0);
438
 
      generator.Emit(OpCodes.Ldloc_0);
439
 
      generator.Emit(OpCodes.Stfld, deleF);
440
 
 
441
 
      //generator.EmitWriteLine("myService.SignalCalled += handler");
442
 
      generator.Emit(OpCodes.Ldloc_0);
443
 
      generator.EmitCall(OpCodes.Callvirt, Service_AddSignalCalledMI, null);
444
 
 
445
 
      //generator.EmitWriteLine("return");
446
 
      generator.Emit(OpCodes.Ret);
447
 
    }
448
 
 
449
 
    public void BuildSignalConstructor(ref TypeBuilder typeB, FieldInfo serviceF, FieldInfo pathF)
450
 
    {
451
 
      Type[] pars = {typeof(Service), typeof(string)};
452
 
      ConstructorBuilder constructor = typeB.DefineConstructor(MethodAttributes.RTSpecialName | 
453
 
                                                               MethodAttributes.Public,
454
 
                                                               CallingConventions.Standard, pars);
455
 
 
456
 
      ILGenerator generator = constructor.GetILGenerator();
457
 
      generator.Emit(OpCodes.Ldarg_0);
458
 
      generator.Emit(OpCodes.Call, this.introspector.Constructor);
459
 
      //generator.EmitWriteLine("service = myService");
460
 
      generator.Emit(OpCodes.Ldarg_1);
461
 
      generator.Emit(OpCodes.Stsfld, serviceF);
462
 
      //generator.EmitWriteLine("this.pathName = pathName");
463
 
      generator.Emit(OpCodes.Ldarg_0);
464
 
      generator.Emit(OpCodes.Ldarg_2);
465
 
      generator.Emit(OpCodes.Stfld, pathF);
466
 
      
467
 
      //generator.EmitWriteLine("return");
468
 
      generator.Emit(OpCodes.Ret);
469
 
    }
470
 
    
471
 
    public void BuildFinalizer (TypeBuilder tb, FieldInfo serviceF, FieldInfo deleF)
472
 
    {
473
 
       // Note that this is a *HORRIBLE* example of how to build a finalizer
474
 
       // It doesn't use the try/finally to chain to Object::Finalize. However,
475
 
       // because that is always going to be a nop, lets just ignore that here.
476
 
       // If you are trying to find the right code, look at what mcs does ;-).
477
 
 
478
 
       MethodBuilder mb = tb.DefineMethod("Finalize",
479
 
                                          MethodAttributes.Family |
480
 
                                          MethodAttributes.HideBySig |
481
 
                                          MethodAttributes.Virtual, 
482
 
                                          typeof (void), 
483
 
                                          new Type [0]);
484
 
       ILGenerator generator = mb.GetILGenerator();
485
 
 
486
 
       //generator.EmitWriteLine("this.service.SignalCalled -= this.delegate_created");
487
 
       generator.Emit (OpCodes.Ldarg_0);
488
 
       generator.Emit (OpCodes.Ldfld, serviceF);
489
 
       generator.Emit (OpCodes.Ldarg_0);
490
 
       generator.Emit (OpCodes.Ldfld, deleF);
491
 
       generator.EmitCall (OpCodes.Callvirt, Service_RemoveSignalCalledMI, null);
492
 
       generator.Emit (OpCodes.Ret);
493
 
    }
494
 
    
495
 
    public object GetSignalProxy()
496
 
    {
497
 
      Type proxyType = Service.ProxyAssembly.GetType(ObjectName + ".SignalProxy");
498
 
 
499
 
      if (proxyType == null) {
500
 
        // Build the type
501
 
        TypeBuilder typeB = Service.Module.DefineType(ObjectName + ".SignalProxy", 
502
 
                                                      TypeAttributes.Public, 
503
 
                                                      this.type);
504
 
        
505
 
        FieldBuilder serviceF = typeB.DefineField("service", 
506
 
                                                  typeof(Service), 
507
 
                                                  FieldAttributes.Private | 
508
 
                                                  FieldAttributes.Static);
509
 
        FieldBuilder pathF = typeB.DefineField("pathName", 
510
 
                                               typeof(string), 
511
 
                                               FieldAttributes.Private);
512
 
 
513
 
        BuildSignalConstructor(ref typeB, serviceF, pathF);
514
 
        
515
 
        // Build the signal handlers
516
 
        foreach (DictionaryEntry interfaceEntry in this.introspector.InterfaceProxies) {
517
 
          InterfaceProxy interfaceProxy = (InterfaceProxy) interfaceEntry.Value;
518
 
          foreach (DictionaryEntry signalEntry in interfaceProxy.Signals) {
519
 
            EventInfo eventE = (EventInfo) signalEntry.Value;
520
 
            BuildSignalHandler(eventE, interfaceProxy, ref typeB, serviceF, pathF);
521
 
          }
522
 
        }
523
 
        
524
 
        proxyType = typeB.CreateType();
525
 
      
526
 
        // Uncomment the following line to produce a DLL of the
527
 
        // constructed assembly which can then be examined using
528
 
        // monodis. Note that in order for this to work you should copy
529
 
        // the client assembly as a dll file so that monodis can pick it
530
 
        // up.
531
 
        //Service.ProxyAssembly.Save("proxy.dll");
532
 
      }
533
 
 
534
 
      Type [] parTypes = new Type[] {typeof(Service), typeof(string)};
535
 
      object [] pars = new object[] {Service, pathName};
536
 
      
537
 
      ConstructorInfo constructor = proxyType.GetConstructor(parTypes);
538
 
      object instance = constructor.Invoke(pars);
539
 
      return instance;
540
 
    }
541
 
      
542
 
    
543
 
    public object GetProxy() 
544
 
    { 
545
 
      Type proxyType = Service.ProxyAssembly.GetType(ObjectName + ".Proxy");
546
 
      
547
 
      if (proxyType == null) {
548
 
        // Build the type
549
 
        TypeBuilder typeB = Service.Module.DefineType(ObjectName + ".Proxy", TypeAttributes.Public, this.type);
550
 
        
551
 
        FieldBuilder serviceF = typeB.DefineField("service", 
552
 
                                                  typeof(Service), 
553
 
                                                  FieldAttributes.Private | 
554
 
                                                  FieldAttributes.Static);
555
 
        FieldBuilder pathF = typeB.DefineField("pathName", 
556
 
                                               typeof(string), 
557
 
                                               FieldAttributes.Private);
558
 
        FieldBuilder deleF = typeB.DefineField("delegate_created", 
559
 
                                               typeof(Service.SignalCalledHandler), 
560
 
                                               FieldAttributes.Private);
561
 
        BuildFinalizer (typeB, serviceF, deleF);
562
 
        
563
 
        MethodInfo signalCalledMI = BuildSignalCalled(ref typeB, serviceF, pathF);
564
 
        BuildConstructor(ref typeB, serviceF, pathF, signalCalledMI, deleF);
565
 
        
566
 
        // Build the methods
567
 
        foreach (DictionaryEntry interfaceEntry in this.introspector.InterfaceProxies) {
568
 
          InterfaceProxy interfaceProxy = (InterfaceProxy) interfaceEntry.Value;
569
 
          foreach (DictionaryEntry methodEntry in interfaceProxy.Methods) {
570
 
            MethodInfo method = (MethodInfo) methodEntry.Value;
571
 
            BuildMethod(method, interfaceProxy, ref typeB, serviceF, pathF);
572
 
          }
573
 
        }
574
 
        
575
 
        proxyType = typeB.CreateType();
576
 
      
577
 
        // Uncomment the following line to produce a DLL of the
578
 
        // constructed assembly which can then be examined using
579
 
        // monodis. Note that in order for this to work you should copy
580
 
        // the client assembly as a dll file so that monodis can pick it
581
 
        // up.
582
 
        //Service.ProxyAssembly.Save(Service.Name + ".proxy.dll");
583
 
      }
584
 
 
585
 
      Type [] parTypes = new Type[] {typeof(Service), typeof(string)};
586
 
      object [] pars = new object[] {Service, pathName};
587
 
      
588
 
      ConstructorInfo constructor = proxyType.GetConstructor(parTypes);
589
 
      object instance = constructor.Invoke(pars);
590
 
      return instance;
591
 
    }
592
 
    
593
 
    private Service Service
594
 
    {
595
 
      get {
596
 
        return this.service;
597
 
      }
598
 
    }
599
 
 
600
 
    private string ObjectName
601
 
    {
602
 
      get {
603
 
        return this.introspector.ToString();
604
 
      }
605
 
    }
606
 
  }
607
 
}
608