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

« back to all changes in this revision

Viewing changes to Tomboy/dbus-sharp/Arguments.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
 
using System;
2
 
using System.Collections;
3
 
using System.Reflection;
4
 
using System.Runtime.InteropServices;
5
 
 
6
 
namespace DBus
7
 
{
8
 
  // Holds the arguments of a message. Provides methods for appending
9
 
  // arguments and to assist in matching .NET types with D-BUS types.
10
 
        public class Arguments : IEnumerable, IDisposable
11
 
  {
12
 
    // Must follow sizeof(DBusMessageIter)
13
 
    internal const int DBusMessageIterSize = 14*4;
14
 
    private static Hashtable dbusTypes = null;
15
 
    private Message message;
16
 
    private IntPtr appenderIter;
17
 
    private IEnumerator enumerator = null;
18
 
    
19
 
    internal Arguments (Message message)
20
 
    {
21
 
      this.appenderIter = Marshal.AllocCoTaskMem(DBusMessageIterSize);
22
 
      this.message = message;
23
 
    }
24
 
 
25
 
    private void Dispose (bool disposing)
26
 
    {
27
 
      Marshal.FreeCoTaskMem(appenderIter);
28
 
    }
29
 
 
30
 
    public void Dispose ()
31
 
    {
32
 
      Dispose (true);
33
 
      GC.SuppressFinalize (this);
34
 
    }
35
 
 
36
 
    ~Arguments()
37
 
    {
38
 
      Dispose (false);
39
 
    }
40
 
 
41
 
    // Checks the suitability of a D-BUS type for supporting a .NET
42
 
    // type.
43
 
    public static bool Suits(Type dbusType, Type type) 
44
 
    {
45
 
      object [] pars = new object[1];
46
 
      pars[0] = type;
47
 
      
48
 
      return (bool) dbusType.InvokeMember("Suits", BindingFlags.Static | BindingFlags.Public | BindingFlags.InvokeMethod, null, null, pars, null);
49
 
    }
50
 
    
51
 
    // Find a suitable match for the given .NET type or throw an
52
 
    // exception if one can't be found.
53
 
    public static Type MatchType(Type type) 
54
 
    {      
55
 
      foreach(Type dbusType in DBusTypes.Values) {
56
 
        if (Suits(dbusType, type)) {
57
 
          return dbusType;
58
 
        }
59
 
      }
60
 
      
61
 
      throw new ApplicationException("No suitable DBUS type found for type '" + type + "'");
62
 
    }
63
 
    
64
 
    // The D-BUS types.
65
 
    public static Hashtable DBusTypes {
66
 
      get 
67
 
        {
68
 
          if (dbusTypes == null) {
69
 
            dbusTypes = new Hashtable();
70
 
 
71
 
            foreach (Type type in Assembly.GetAssembly(typeof(DBusType.IDBusType)).GetTypes()) {
72
 
              if (type != typeof(DBusType.IDBusType) && typeof(DBusType.IDBusType).IsAssignableFrom(type)) {
73
 
                dbusTypes.Add(GetCode(type), type);
74
 
              }
75
 
            }
76
 
          }
77
 
          
78
 
          return dbusTypes;
79
 
        }
80
 
    }
81
 
    
82
 
    // Append an argument
83
 
    public void Append(DBusType.IDBusType dbusType)
84
 
    {
85
 
      dbusType.Append(appenderIter);
86
 
    }
87
 
    
88
 
    // Append an argument of the specified type
89
 
    private void AppendType(Type type, object val)
90
 
    {
91
 
      object [] pars = new Object[2];
92
 
      pars[0] = val;
93
 
      pars[1] = message.Service;
94
 
      DBusType.IDBusType dbusType = (DBusType.IDBusType) Activator.CreateInstance(MatchType(type), pars);
95
 
      Append(dbusType);
96
 
    }
97
 
    
98
 
    // Append the results of a method call
99
 
    public void AppendResults(MethodInfo method, object retVal, object [] parameters) 
100
 
    {
101
 
      InitAppending();
102
 
 
103
 
      if (method.ReturnType != typeof(void)) {
104
 
        AppendType(method.ReturnType, retVal);
105
 
      }
106
 
      
107
 
      for (int i = 0; i < method.GetParameters().Length; i++) {
108
 
        ParameterInfo par = method.GetParameters()[i];
109
 
        if (par.IsOut || par.ParameterType.ToString().EndsWith("&")) {
110
 
          // It's an OUT or INOUT parameter.
111
 
          AppendType(par.ParameterType.UnderlyingSystemType, parameters[i]);
112
 
        }
113
 
      }
114
 
    }
115
 
    
116
 
    // Get the parameters
117
 
    public object[] GetParameters(MethodInfo method) 
118
 
    {
119
 
      ParameterInfo[] pars = method.GetParameters();
120
 
      ArrayList paramList = new ArrayList();
121
 
      
122
 
      enumerator = GetEnumerator();
123
 
      foreach (ParameterInfo par in pars) {
124
 
        if (!par.IsOut) {
125
 
          // It's an IN or INOUT paramter.
126
 
          enumerator.MoveNext();
127
 
          DBusType.IDBusType dbusType = (DBusType.IDBusType) enumerator.Current;
128
 
          paramList.Add(dbusType.Get(par.ParameterType));
129
 
        } else {
130
 
          // It's an OUT so just create a parameter for it
131
 
          object var = null;
132
 
          paramList.Add(var);
133
 
        }
134
 
      }
135
 
      
136
 
      return paramList.ToArray();
137
 
    }
138
 
 
139
 
    // Parse the IN & REF parameters to a method and return the types in a list.
140
 
    public static object[] ParseInParameters(MethodInfo method)
141
 
    {
142
 
      ArrayList types = new ArrayList();
143
 
 
144
 
      ParameterInfo[] pars = method.GetParameters();
145
 
      foreach (ParameterInfo par in pars) {
146
 
        if (!par.IsOut) {
147
 
          types.Add(MatchType(par.ParameterType));
148
 
        }
149
 
      }
150
 
 
151
 
      return types.ToArray();
152
 
    }
153
 
 
154
 
    // Parse the OUT & REF parameters to a method and return the types in a list.
155
 
    public static object[] ParseOutParameters(MethodInfo method)
156
 
    {
157
 
      ArrayList types = new ArrayList();
158
 
 
159
 
      ParameterInfo[] pars = method.GetParameters();
160
 
      foreach (ParameterInfo par in pars) {
161
 
        if (par.IsOut || par.ParameterType.ToString().EndsWith("&")) {
162
 
          types.Add(MatchType(par.ParameterType));
163
 
        }
164
 
      }
165
 
 
166
 
      return types.ToArray();
167
 
    }
168
 
    
169
 
    // Get the appropriate constructor for a D-BUS type
170
 
    public static ConstructorInfo GetDBusTypeConstructor(Type dbusType, Type type) 
171
 
    {
172
 
      Type constructorType;
173
 
 
174
 
      if (type.IsArray)
175
 
        constructorType = typeof (System.Array);
176
 
      else if (type.IsEnum)
177
 
        constructorType = Enum.GetUnderlyingType (type);
178
 
      else
179
 
        constructorType = type.UnderlyingSystemType;
180
 
 
181
 
      ConstructorInfo constructor = dbusType.GetConstructor(new Type[] {constructorType, typeof(Service)});
182
 
      if (constructor == null)
183
 
        throw new ArgumentException("There is no valid constructor for '" + dbusType + "' from type '" + type + "'");
184
 
      
185
 
      return constructor;
186
 
    }
187
 
 
188
 
    // Get the type code for a given D-BUS type
189
 
    public static char GetCode(Type dbusType) 
190
 
    {
191
 
      return (char) dbusType.InvokeMember("Code", BindingFlags.Static | BindingFlags.GetField, null, null, null);
192
 
    }
193
 
 
194
 
    // Get the type code for a given D-BUS type as a string
195
 
    public static string GetCodeAsString (Type dbusType)
196
 
    {
197
 
      return GetCode (dbusType).ToString ();
198
 
    }
199
 
 
200
 
    // Get a complete method signature
201
 
    public override string ToString() 
202
 
    {
203
 
      IntPtr iter = Marshal.AllocCoTaskMem(DBusMessageIterSize);
204
 
      string key = "";
205
 
 
206
 
      // Iterate through the parameters getting the type codes to a string
207
 
      bool notEmpty = dbus_message_iter_init(message.RawMessage, iter);
208
 
 
209
 
      if (notEmpty) {
210
 
        do {
211
 
          char code = (char) dbus_message_iter_get_arg_type(iter);
212
 
          if (code == '\0')
213
 
            return key;
214
 
          
215
 
          key += code;
216
 
        } while (dbus_message_iter_next(iter));
217
 
      }
218
 
 
219
 
      Marshal.FreeCoTaskMem(iter);
220
 
 
221
 
      return key;
222
 
    }
223
 
    
224
 
    // Move to the next parameter
225
 
    public DBusType.IDBusType GetNext() 
226
 
    {
227
 
      enumerator.MoveNext();
228
 
      return (DBusType.IDBusType) enumerator.Current;
229
 
    }
230
 
 
231
 
    // Begin appending
232
 
    public void InitAppending() 
233
 
    {
234
 
      dbus_message_iter_init_append(message.RawMessage, appenderIter);
235
 
    }
236
 
 
237
 
    // Get the enumerator
238
 
    public IEnumerator GetEnumerator()
239
 
    {
240
 
      return new ArgumentsEnumerator(this);
241
 
    }
242
 
 
243
 
    private class ArgumentsEnumerator : IEnumerator
244
 
    {
245
 
      private Arguments arguments;
246
 
      private bool started = false;
247
 
      private bool notEmpty = false;
248
 
      private IntPtr iter = Marshal.AllocCoTaskMem(Arguments.DBusMessageIterSize);
249
 
      
250
 
      public ArgumentsEnumerator(Arguments arguments)
251
 
      {
252
 
        this.arguments = arguments;
253
 
        Reset();
254
 
      }
255
 
      
256
 
      ~ArgumentsEnumerator()
257
 
      {
258
 
        Marshal.FreeCoTaskMem(iter);
259
 
      }
260
 
 
261
 
      public bool MoveNext()
262
 
      {
263
 
        if (started) {
264
 
          return dbus_message_iter_next(iter);
265
 
        } else {
266
 
          started = true;
267
 
          return notEmpty;
268
 
        }
269
 
      }
270
 
      
271
 
      public void Reset()
272
 
      {
273
 
        notEmpty = dbus_message_iter_init(arguments.message.RawMessage, iter);
274
 
        started = false;
275
 
      }
276
 
      
277
 
      public object Current
278
 
      {
279
 
        get
280
 
          {
281
 
            object [] pars = new Object[2];
282
 
            pars[0] = iter;
283
 
            pars[1] = arguments.message.Service;
284
 
            
285
 
            Type type = (Type) DBusTypes[(char) dbus_message_iter_get_arg_type(iter)];
286
 
            DBusType.IDBusType dbusType = (DBusType.IDBusType) Activator.CreateInstance(type, pars);
287
 
 
288
 
            return dbusType;
289
 
          }
290
 
      }
291
 
    }
292
 
 
293
 
    [DllImport("dbus-1")]
294
 
    private extern static void dbus_message_iter_init_append(IntPtr rawMessage, IntPtr iter);
295
 
 
296
 
    [DllImport("dbus-1")]
297
 
    private extern static bool dbus_message_iter_has_next(IntPtr iter);
298
 
 
299
 
    [DllImport("dbus-1")]
300
 
    private extern static bool dbus_message_iter_next(IntPtr iter);
301
 
 
302
 
    [DllImport("dbus-1")]
303
 
    private extern static bool dbus_message_iter_init(IntPtr rawMessage, IntPtr iter);
304
 
 
305
 
    [DllImport("dbus-1")]
306
 
    private extern static int dbus_message_iter_get_arg_type(IntPtr iter);
307
 
  }
308
 
}