~ubuntu-branches/debian/jessie/banshee-community-extensions/jessie

« back to all changes in this revision

Viewing changes to .pc/0001-Use-DBus-instead-of-NDesk.DBus.patch/src/Telepathy/Banshee.Telepathy/NDesk.DBus/Introspection.cs

  • Committer: Package Import Robot
  • Author(s): Chow Loong Jin
  • Date: 2011-09-20 18:45:46 UTC
  • mfrom: (1.2.9 upstream) (5.1.8 experimental)
  • Revision ID: package-import@ubuntu.com-20110920184546-3ahue2qplydc4t0e
Tags: 2.2.0-1
* [4940fab] Imported Upstream version 2.2.0
  + Notable bug fixes:
    - Karaoke: Fix crash when switching to Now Playing
    - Lyrics: Fix crash when switching to Now Playing

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
// Copyright 2006 Alp Toker <alp@atoker.com>
2
 
// This software is made available under the MIT License
3
 
// See COPYING for details
4
 
 
5
 
using System;
6
 
using System.Collections.Generic;
7
 
using System.IO;
8
 
using System.Xml;
9
 
using System.Text;
10
 
using System.Reflection;
11
 
 
12
 
namespace NDesk.DBus
13
 
{
14
 
        //TODO: complete this class
15
 
        class Introspector
16
 
        {
17
 
                const string NAMESPACE = "http://www.freedesktop.org/standards/dbus";
18
 
                const string PUBLIC_IDENTIFIER = "-//freedesktop//DTD D-BUS Object Introspection 1.0//EN";
19
 
                const string SYSTEM_IDENTIFIER = "http://www.freedesktop.org/standards/dbus/1.0/introspect.dtd";
20
 
 
21
 
                public StringBuilder sb;
22
 
                public string xml;
23
 
                public ObjectPath root_path = ObjectPath.Root;
24
 
                public bool ExtendedAnnotations = false;
25
 
 
26
 
                protected XmlWriter writer;
27
 
 
28
 
                public Introspector ()
29
 
                {
30
 
                        XmlWriterSettings settings = new XmlWriterSettings ();
31
 
                        settings.Indent = true;
32
 
                        settings.IndentChars = ("  ");
33
 
                        settings.OmitXmlDeclaration = true;
34
 
 
35
 
                        sb = new StringBuilder ();
36
 
 
37
 
                        writer = XmlWriter.Create (sb, settings);
38
 
                }
39
 
 
40
 
                static string GetProductDescription ()
41
 
                {
42
 
                        String version;
43
 
 
44
 
                        Assembly assembly = Assembly.GetExecutingAssembly ();
45
 
                        AssemblyName aname = assembly.GetName ();
46
 
 
47
 
                        AssemblyInformationalVersionAttribute iversion = Attribute.GetCustomAttribute (assembly, typeof (AssemblyInformationalVersionAttribute)) as AssemblyInformationalVersionAttribute;
48
 
 
49
 
                        if (iversion != null)
50
 
                                version = iversion.InformationalVersion;
51
 
                        else
52
 
                                version = aname.Version.ToString ();
53
 
 
54
 
                        return aname.Name + " " + version;
55
 
                }
56
 
 
57
 
                public void WriteStart ()
58
 
                {
59
 
                        writer.WriteDocType ("node", PUBLIC_IDENTIFIER, SYSTEM_IDENTIFIER, null);
60
 
 
61
 
                        writer.WriteComment (" " + GetProductDescription () + " ");
62
 
 
63
 
                        //the root node element
64
 
                        writer.WriteStartElement ("node");
65
 
                }
66
 
 
67
 
                public void WriteNode (string name)
68
 
                {
69
 
                        writer.WriteStartElement ("node");
70
 
                        writer.WriteAttributeString ("name", name);
71
 
                        writer.WriteEndElement ();
72
 
                }
73
 
 
74
 
                public void WriteEnd ()
75
 
                {
76
 
                        /*
77
 
                        WriteEnum (typeof (org.freedesktop.DBus.NameFlag));
78
 
                        WriteEnum (typeof (org.freedesktop.DBus.NameReply));
79
 
                        WriteEnum (typeof (org.freedesktop.DBus.ReleaseNameReply));
80
 
                        WriteEnum (typeof (org.freedesktop.DBus.StartReply));
81
 
                        WriteInterface (typeof (org.freedesktop.DBus.IBus));
82
 
                        */
83
 
 
84
 
                        writer.WriteEndElement ();
85
 
 
86
 
                        writer.Flush ();
87
 
                        xml = sb.ToString ();
88
 
                }
89
 
 
90
 
                //public void WriteNode ()
91
 
                public void WriteType (Type target_type)
92
 
                {
93
 
                        //writer.WriteStartElement ("node");
94
 
 
95
 
                        //TODO: non-well-known introspection has paths as well, which we don't do yet. read the spec again
96
 
                        //hackishly just remove the root '/' to make the path relative for now
97
 
                        //writer.WriteAttributeString ("name", target_path.Value.Substring (1));
98
 
                        //writer.WriteAttributeString ("name", "test");
99
 
 
100
 
                        //reflect our own interface manually
101
 
                        WriteInterface (typeof (org.freedesktop.DBus.Introspectable));
102
 
 
103
 
                        //reflect the target interface
104
 
                        if (target_type != null) {
105
 
                                WriteInterface (target_type);
106
 
 
107
 
                                foreach (Type ifType in target_type.GetInterfaces ())
108
 
                                        WriteInterface (ifType);
109
 
                        }
110
 
 
111
 
                        //TODO: review recursion of interfaces and inheritance hierarchy
112
 
 
113
 
                        //writer.WriteEndElement ();
114
 
                }
115
 
 
116
 
                public void WriteArg (ParameterInfo pi)
117
 
                {
118
 
                        WriteArg (pi.ParameterType, Mapper.GetArgumentName (pi), pi.IsOut, false);
119
 
                }
120
 
 
121
 
                public void WriteArgReverse (ParameterInfo pi)
122
 
                {
123
 
                        WriteArg (pi.ParameterType, Mapper.GetArgumentName (pi), pi.IsOut, true);
124
 
                }
125
 
 
126
 
                //TODO: clean up and get rid of reverse (or argIsOut) parm
127
 
                public void WriteArg (Type argType, string argName, bool argIsOut, bool reverse)
128
 
                {
129
 
                        argType = argIsOut ? argType.GetElementType () : argType;
130
 
                        if (argType == typeof (void))
131
 
                                return;
132
 
 
133
 
                        writer.WriteStartElement ("arg");
134
 
 
135
 
                        if (!String.IsNullOrEmpty (argName))
136
 
                                writer.WriteAttributeString ("name", argName);
137
 
 
138
 
                        //we can't rely on the default direction (qt-dbus requires a direction at time of writing), so we use a boolean to reverse the parameter direction and make it explicit
139
 
 
140
 
                        if (argIsOut)
141
 
                                writer.WriteAttributeString ("direction", !reverse ? "out" : "in");
142
 
                        else
143
 
                                writer.WriteAttributeString ("direction", !reverse ? "in" : "out");
144
 
 
145
 
                        Signature sig = Signature.GetSig (argType);
146
 
 
147
 
                        //TODO: avoid writing null (DType.Invalid) to the XML stream
148
 
                        writer.WriteAttributeString ("type", sig.Value);
149
 
 
150
 
                        //annotations aren't valid in an arg element, so this is disabled
151
 
                        //if (argType.IsEnum)
152
 
                        //      WriteAnnotation ("org.ndesk.DBus.Enum", Mapper.GetInterfaceName (argType));
153
 
 
154
 
                        writer.WriteEndElement ();
155
 
                }
156
 
 
157
 
                public void WriteMethod (MethodInfo mi)
158
 
                {
159
 
                        writer.WriteStartElement ("method");
160
 
                        writer.WriteAttributeString ("name", mi.Name);
161
 
 
162
 
                        foreach (ParameterInfo pi in mi.GetParameters ())
163
 
                                WriteArg (pi);
164
 
 
165
 
                        //Mono <= 1.1.13 doesn't support MethodInfo.ReturnParameter, so avoid it
166
 
                        //WriteArgReverse (mi.ReturnParameter);
167
 
                        WriteArg (mi.ReturnType, Mapper.GetArgumentName (mi.ReturnTypeCustomAttributes, "ret"), false, true);
168
 
 
169
 
                        WriteAnnotations (mi);
170
 
 
171
 
                        writer.WriteEndElement ();
172
 
                }
173
 
 
174
 
                public void WriteProperty (PropertyInfo pri)
175
 
                {
176
 
                        //expose properties as dbus properties
177
 
                        writer.WriteStartElement ("property");
178
 
                        writer.WriteAttributeString ("name", pri.Name);
179
 
                        writer.WriteAttributeString ("type", Signature.GetSig (pri.PropertyType).Value);
180
 
                        string access = (pri.CanRead ? "read" : String.Empty) + (pri.CanWrite ? "write" : String.Empty);
181
 
                        writer.WriteAttributeString ("access", access);
182
 
                        WriteAnnotations (pri);
183
 
                        writer.WriteEndElement ();
184
 
 
185
 
                        //expose properties as methods also
186
 
                        //it may not be worth doing this in the long run
187
 
                        /*
188
 
                        if (pri.CanRead) {
189
 
                                writer.WriteStartElement ("method");
190
 
                                writer.WriteAttributeString ("name", "Get" + pri.Name);
191
 
                                WriteArgReverse (pri.GetGetMethod ().ReturnParameter);
192
 
                                writer.WriteEndElement ();
193
 
                        }
194
 
 
195
 
                        if (pri.CanWrite) {
196
 
                                writer.WriteStartElement ("method");
197
 
                                writer.WriteAttributeString ("name", "Set" + pri.Name);
198
 
                                foreach (ParameterInfo pi in pri.GetSetMethod ().GetParameters ())
199
 
                                        WriteArg (pi);
200
 
                                writer.WriteEndElement ();
201
 
                        }
202
 
                        */
203
 
                }
204
 
 
205
 
                public void WriteSignal (EventInfo ei)
206
 
                {
207
 
                        writer.WriteStartElement ("signal");
208
 
                        writer.WriteAttributeString ("name", ei.Name);
209
 
 
210
 
                        foreach (ParameterInfo pi in ei.EventHandlerType.GetMethod ("Invoke").GetParameters ())
211
 
                                WriteArgReverse (pi);
212
 
 
213
 
                        if (ExtendedAnnotations) {
214
 
                                string handlerName = Mapper.GetInterfaceName (ei.EventHandlerType);
215
 
                                WriteAnnotation ("org.ndesk.DBus.SignalHandler", handlerName);
216
 
                        }
217
 
 
218
 
                        WriteAnnotations (ei);
219
 
 
220
 
                        //no need to consider the delegate return value as dbus doesn't support it
221
 
                        writer.WriteEndElement ();
222
 
                }
223
 
 
224
 
                const BindingFlags relevantBindingFlags = BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly;
225
 
 
226
 
                public void WriteInterface (Type type)
227
 
                {
228
 
                        if (type == null)
229
 
                                return;
230
 
 
231
 
                        //TODO: this is unreliable, fix it
232
 
                        if (!Mapper.IsPublic (type))
233
 
                                return;
234
 
 
235
 
                        writer.WriteStartElement ("interface");
236
 
 
237
 
                        writer.WriteAttributeString ("name", Mapper.GetInterfaceName (type));
238
 
 
239
 
                        /*
240
 
                        foreach (MemberInfo mbi in type.GetMembers (relevantBindingFlags)) {
241
 
                                switch (mbi.MemberType) {
242
 
                                        case MemberTypes.Method:
243
 
                                                if (!((MethodInfo)mbi).IsSpecialName)
244
 
                                                        WriteMethod ((MethodInfo)mbi);
245
 
                                                break;
246
 
                                        case MemberTypes.Event:
247
 
                                                WriteSignal ((EventInfo)mbi);
248
 
                                                break;
249
 
                                        case MemberTypes.Property:
250
 
                                                WriteProperty ((PropertyInfo)mbi);
251
 
                                                break;
252
 
                                        default:
253
 
                                                Console.Error.WriteLine ("Warning: Unhandled MemberType '{0}' encountered while introspecting {1}", mbi.MemberType, type.FullName);
254
 
                                                break;
255
 
                                }
256
 
                        }
257
 
                        */
258
 
 
259
 
                        foreach (MethodInfo mi in type.GetMethods (relevantBindingFlags))
260
 
                                if (!mi.IsSpecialName)
261
 
                                        WriteMethod (mi);
262
 
 
263
 
                        foreach (EventInfo ei in type.GetEvents (relevantBindingFlags))
264
 
                                WriteSignal (ei);
265
 
 
266
 
                        foreach (PropertyInfo pri in type.GetProperties (relevantBindingFlags))
267
 
                                WriteProperty (pri);
268
 
 
269
 
                        //TODO: indexers
270
 
 
271
 
                        //TODO: attributes as annotations?
272
 
 
273
 
                        writer.WriteEndElement ();
274
 
 
275
 
                        //this recursion seems somewhat inelegant
276
 
                        WriteInterface (type.BaseType);
277
 
                }
278
 
 
279
 
                public void WriteAnnotations (ICustomAttributeProvider attrProvider)
280
 
                {
281
 
                        if (Mapper.IsDeprecated (attrProvider))
282
 
                                WriteAnnotation ("org.freedesktop.DBus.Deprecated", "true");
283
 
                }
284
 
 
285
 
                public void WriteAnnotation (string name, string value)
286
 
                {
287
 
                        writer.WriteStartElement ("annotation");
288
 
 
289
 
                        writer.WriteAttributeString ("name", name);
290
 
                        writer.WriteAttributeString ("value", value);
291
 
 
292
 
                        writer.WriteEndElement ();
293
 
                }
294
 
 
295
 
                //this is not in the spec, and is not finalized
296
 
                public void WriteEnum (Type type)
297
 
                {
298
 
                        writer.WriteStartElement ("enum");
299
 
                        writer.WriteAttributeString ("name", Mapper.GetInterfaceName (type));
300
 
                        writer.WriteAttributeString ("type", Signature.GetSig (type.GetElementType ()).Value);
301
 
                        writer.WriteAttributeString ("flags", (type.IsDefined (typeof (FlagsAttribute), false)) ? "true" : "false");
302
 
 
303
 
                        string[] names = Enum.GetNames (type);
304
 
 
305
 
                        int i = 0;
306
 
                        foreach (Enum val in Enum.GetValues (type)) {
307
 
                                writer.WriteStartElement ("element");
308
 
                                writer.WriteAttributeString ("name", names[i++]);
309
 
                                writer.WriteAttributeString ("value", val.ToString ("d"));
310
 
                                writer.WriteEndElement ();
311
 
                        }
312
 
 
313
 
                        writer.WriteEndElement ();
314
 
                }
315
 
        }
316
 
}