diff options
author | Owen Fraser-Green <owen@discobabe.net> | 2004-03-23 18:07:48 +0000 |
---|---|---|
committer | Owen Fraser-Green <owen@discobabe.net> | 2004-03-23 18:07:48 +0000 |
commit | 632d54e0dbf5e405258be7afffbaa48942c06cbc (patch) | |
tree | 0b3495f8a0753d427078a90e585dc53a2287200d /mono | |
parent | 0a673a8cd751d9eae14f3f5d0eeebf749b07bf09 (diff) |
Added InterfaceProxy to Mono bindings to avoid having to generate a proxy for every registered object. Also added object_path functions to dbus-message.
Diffstat (limited to 'mono')
-rw-r--r-- | mono/Arguments.cs | 16 | ||||
-rw-r--r-- | mono/Handler.cs | 56 | ||||
-rw-r--r-- | mono/InterfaceProxy.cs | 86 | ||||
-rw-r--r-- | mono/Introspector.cs | 127 | ||||
-rw-r--r-- | mono/Makefile.am | 1 | ||||
-rw-r--r-- | mono/Message.cs | 12 | ||||
-rw-r--r-- | mono/ProxyBuilder.cs | 81 | ||||
-rw-r--r-- | mono/Service.cs | 4 |
8 files changed, 206 insertions, 177 deletions
diff --git a/mono/Arguments.cs b/mono/Arguments.cs index ac88d6a7..0df205c3 100644 --- a/mono/Arguments.cs +++ b/mono/Arguments.cs @@ -170,22 +170,6 @@ namespace DBus return constructor; } - // Get the signature of a method - public static string ParseParameters(MethodInfo method) - { - ParameterInfo[] pars = method.GetParameters(); - string key = ""; - - foreach (ParameterInfo par in pars) { - if (!par.IsOut) { - Type dbusType = MatchType(par.ParameterType); - key += GetCode(dbusType); - } - } - - return key; - } - // Get the type code for a given D-BUS type public static char GetCode(Type dbusType) { diff --git a/mono/Handler.cs b/mono/Handler.cs index d565b7ec..a854c9ce 100644 --- a/mono/Handler.cs +++ b/mono/Handler.cs @@ -12,7 +12,6 @@ namespace DBus private string pathName = null; private Introspector introspector = null; private object handledObject = null; - private Hashtable handledMethods = null; private DBusObjectPathVTable vTable; private Connection connection; private Service service; @@ -99,33 +98,20 @@ namespace DBus throw new OutOfMemoryException(); } - private void RegisterMethod(MethodInfo method) - { - string key = method.Name + " " + Arguments.ParseParameters(method); - handledMethods.Add(key, method); - } - public object HandledObject { - get - { - return this.handledObject; - } + get { + return this.handledObject; + } - set - { - this.handledObject = value; - - object[] attributes; - - // Register the methods - this.handledMethods = new Hashtable(); - this.introspector = new Introspector(value.GetType()); - - foreach (MethodInfo method in this.introspector.Methods) { - RegisterMethod(method); - } - } + set { + this.handledObject = value; + + object[] attributes; + + // Register the methods + this.introspector = Introspector.GetIntrospector(value.GetType()); + } } public int Filter_Called(IntPtr rawConnection, @@ -169,22 +155,14 @@ namespace DBus private Result HandleMethod(MethodCall methodCall) { methodCall.Service = service; - - // Check the interface name matches - if (methodCall.InterfaceName != this.introspector.InterfaceName) { - return Result.NotYetHandled; - } - - // Iterate through getting the type codes - string key = methodCall.Name + " " + methodCall.Arguments; - - // Check it's one of our methods - if (!handledMethods.Contains(key)) { + + InterfaceProxy interfaceProxy = this.introspector.GetInterface(methodCall.InterfaceName); + if (interfaceProxy == null || !interfaceProxy.HasMethod(methodCall.Key)) { + // No such interface here. return Result.NotYetHandled; } - - // Got it! - MethodInfo method = (MethodInfo) handledMethods[key]; + + MethodInfo method = interfaceProxy.GetMethod(methodCall.Key); // Now call the method. FIXME: Error handling object [] args = methodCall.Arguments.GetParameters(method); diff --git a/mono/InterfaceProxy.cs b/mono/InterfaceProxy.cs new file mode 100644 index 00000000..6ccc9636 --- /dev/null +++ b/mono/InterfaceProxy.cs @@ -0,0 +1,86 @@ +namespace DBus +{ + using System; + using System.Collections; + using System.Reflection; + + internal class InterfaceProxy + { + private static Hashtable interfaceProxies = new Hashtable(); + private Hashtable methods = null; + + private string interfaceName; + + private InterfaceProxy(Type type) + { + object[] attributes = type.GetCustomAttributes(typeof(InterfaceAttribute), true); + InterfaceAttribute interfaceAttribute = (InterfaceAttribute) attributes[0]; + this.interfaceName = interfaceAttribute.InterfaceName; + AddMethods(type); + } + + private void AddMethods(Type type) + { + this.methods = new Hashtable(); + foreach (MethodInfo method in type.GetMethods(BindingFlags.Public | + BindingFlags.Instance | + BindingFlags.DeclaredOnly)) { + object[] attributes = method.GetCustomAttributes(typeof(MethodAttribute), true); + if (attributes.GetLength(0) > 0) { + methods.Add(GetKey(method), method); + } + } + } + + + public static InterfaceProxy GetInterface(Type type) + { + if (!interfaceProxies.Contains(type)) { + interfaceProxies[type] = new InterfaceProxy(type); + } + + return (InterfaceProxy) interfaceProxies[type]; + } + + public bool HasMethod(string key) + { + return this.Methods.Contains(key); + } + + public MethodInfo GetMethod(string key) + { + return (MethodInfo) this.Methods[key]; + } + + private string GetKey(MethodInfo method) + { + ParameterInfo[] pars = method.GetParameters(); + string key = method.Name + " "; + + foreach (ParameterInfo par in pars) { + if (!par.IsOut) { + Type dbusType = Arguments.MatchType(par.ParameterType); + key += Arguments.GetCode(dbusType); + } + } + + return key; + } + + public Hashtable Methods + { + get { + return this.methods; + } + } + + public string InterfaceName + { + get { + return this.interfaceName; + } + } + } +} + + diff --git a/mono/Introspector.cs b/mono/Introspector.cs index c7b9d05b..8e97abc6 100644 --- a/mono/Introspector.cs +++ b/mono/Introspector.cs @@ -10,97 +10,72 @@ namespace DBus internal class Introspector { private Type type; - private string interfaceName; + private static Hashtable introspectors = new Hashtable(); + private Hashtable interfaceProxies = null; - public Introspector(Type type) { - object[] attributes = type.GetCustomAttributes(typeof(InterfaceAttribute), true); - if (attributes.Length != 1) - throw new ApplicationException("Type '" + type + "' is not a D-BUS interface."); - - InterfaceAttribute interfaceAttribute = (InterfaceAttribute) attributes[0]; - - this.interfaceName = interfaceAttribute.InterfaceName; + public static Introspector GetIntrospector(Type type) + { + if (!introspectors.Contains(type)) { + introspectors[type] = new Introspector(type); + } + + return (Introspector) introspectors[type]; + } + + private Introspector(Type type) + { + interfaceProxies = new Hashtable(); + AddType(type); this.type = type; } - public string InterfaceName + private void AddType(Type type) { - get - { - return this.interfaceName; - } + if (type == typeof(object)) { + // Base case + return; + } + + object[] attributes = type.GetCustomAttributes(typeof(InterfaceAttribute), false); + if (attributes.Length >= 1) { + // This is a D-BUS interface so add it to the hashtable + InterfaceProxy interfaceProxy = InterfaceProxy.GetInterface(type); + interfaceProxies.Add(interfaceProxy.InterfaceName, interfaceProxy); + } + + AddType(type.BaseType); + } + + public InterfaceProxy GetInterface(string interfaceName) { + if (interfaceProxies.Contains(interfaceName)) { + return (InterfaceProxy) interfaceProxies[interfaceName]; + } else { + return null; + } } - public ConstructorInfo Constructor + public Hashtable InterfaceProxies { - get - { - ConstructorInfo ret = this.type.GetConstructor(new Type[0]); - if (ret != null) { - return ret; - } else { - return typeof(object).GetConstructor(new Type[0]); - } - } + get { + return this.interfaceProxies; + } } - public IntrospectorMethods Methods + public ConstructorInfo Constructor { - get - { - return new IntrospectorMethods(this.type); + get { + ConstructorInfo ret = this.type.GetConstructor(new Type[0]); + if (ret != null) { + return ret; + } else { + return typeof(object).GetConstructor(new Type[0]); } + } } - public class IntrospectorMethods : IEnumerable + public override string ToString() { - private Type type; - - public IntrospectorMethods(Type type) - { - this.type = type; - } - - public IEnumerator GetEnumerator() - { - return new MethodEnumerator(this.type.GetMethods(BindingFlags.Public|BindingFlags.Instance).GetEnumerator()); - } - - private class MethodEnumerator : IEnumerator - { - private IEnumerator enumerator; - - public MethodEnumerator(IEnumerator enumerator) - { - this.enumerator = enumerator; - } - - public bool MoveNext() - { - while (enumerator.MoveNext()) { - MethodInfo method = (MethodInfo) enumerator.Current; - object[] attributes = method.GetCustomAttributes(typeof(MethodAttribute), true); - if (attributes.GetLength(0) > 0) { - return true; - } - } - - return false; - } - - public void Reset() - { - enumerator.Reset(); - } - - public object Current - { - get - { - return enumerator.Current; - } - } - } + return this.type.ToString(); } } } diff --git a/mono/Makefile.am b/mono/Makefile.am index 6483f4ed..b35a5c42 100644 --- a/mono/Makefile.am +++ b/mono/Makefile.am @@ -12,6 +12,7 @@ DBUS_SHARP_FILES= \ Error.cs \ Handler.cs \ InterfaceAttribute.cs \ + InterfaceProxy.cs \ Introspector.cs \ Message.cs \ MethodAttribute.cs \ diff --git a/mono/Message.cs b/mono/Message.cs index 2f5270dd..a1ff220c 100644 --- a/mono/Message.cs +++ b/mono/Message.cs @@ -35,6 +35,7 @@ namespace DBus protected string pathName = null; protected string interfaceName = null; protected string name = null; + private string key= null; protected Message() { @@ -263,6 +264,17 @@ namespace DBus } } + public string Key + { + get { + if (this.key == null) { + this.key = Name + " " + Arguments; + } + + return this.key; + } + } + public Arguments Arguments { get diff --git a/mono/ProxyBuilder.cs b/mono/ProxyBuilder.cs index 8e170c74..06bdeecb 100644 --- a/mono/ProxyBuilder.cs +++ b/mono/ProxyBuilder.cs @@ -50,13 +50,13 @@ namespace DBus this.service = service; this.pathName = pathName; this.type = type; - this.introspector = new Introspector(type); + this.introspector = Introspector.GetIntrospector(type); } private void BuildMethod(MethodInfo method, + InterfaceProxy interfaceProxy, ref TypeBuilder typeB, FieldInfo serviceF, - FieldInfo interfaceF, FieldInfo pathF) { ParameterInfo[] pars = method.GetParameters(); @@ -95,7 +95,7 @@ namespace DBus generator.Emit(OpCodes.Ldsfld, serviceF); generator.Emit(OpCodes.Ldarg_0); generator.Emit(OpCodes.Ldfld, pathF); - generator.Emit(OpCodes.Ldsfld, interfaceF); + generator.Emit(OpCodes.Ldstr, interfaceProxy.InterfaceName); generator.Emit(OpCodes.Ldstr, method.Name); generator.Emit(OpCodes.Newobj, MethodCall_C); generator.Emit(OpCodes.Stloc_0); @@ -190,9 +190,9 @@ namespace DBus } } - public void BuildConstructor(ref TypeBuilder typeB, FieldInfo serviceF, FieldInfo interfaceF, FieldInfo pathF) + public void BuildConstructor(ref TypeBuilder typeB, FieldInfo serviceF, FieldInfo pathF) { - Type[] pars = {typeof(Service), typeof(string), typeof(string)}; + Type[] pars = {typeof(Service), typeof(string)}; ConstructorBuilder constructor = typeB.DefineConstructor(MethodAttributes.RTSpecialName | MethodAttributes.Public, CallingConventions.Standard, pars); @@ -202,10 +202,8 @@ namespace DBus generator.Emit(OpCodes.Call, this.introspector.Constructor); generator.Emit(OpCodes.Ldarg_1); generator.Emit(OpCodes.Stsfld, serviceF); - generator.Emit(OpCodes.Ldarg_2); - generator.Emit(OpCodes.Stsfld, interfaceF); generator.Emit(OpCodes.Ldarg_0); - generator.Emit(OpCodes.Ldarg_3); + generator.Emit(OpCodes.Ldarg_2); generator.Emit(OpCodes.Stfld, pathF); generator.Emit(OpCodes.Ret); @@ -216,29 +214,28 @@ namespace DBus // Build the type TypeBuilder typeB = ServiceModuleBuilder.DefineType(ProxyName, TypeAttributes.Public, this.type); - //type.AddInterfaceImplementation(typeof(IProxy)); FieldBuilder serviceF = typeB.DefineField("service", typeof(Service), FieldAttributes.Private | FieldAttributes.Static); - FieldBuilder interfaceF = typeB.DefineField("interfaceName", - typeof(string), - FieldAttributes.Private | - FieldAttributes.Static); FieldBuilder pathF = typeB.DefineField("pathName", typeof(string), FieldAttributes.Private); - BuildConstructor(ref typeB, serviceF, interfaceF, pathF); + BuildConstructor(ref typeB, serviceF, pathF); // Build the methods - foreach (MethodInfo method in this.introspector.Methods) { - BuildMethod(method, ref typeB, serviceF, interfaceF, pathF); + foreach (DictionaryEntry interfaceEntry in this.introspector.InterfaceProxies) { + InterfaceProxy interfaceProxy = (InterfaceProxy) interfaceEntry.Value; + foreach (DictionaryEntry methodEntry in interfaceProxy.Methods) { + MethodInfo method = (MethodInfo) methodEntry.Value; + BuildMethod(method, interfaceProxy, ref typeB, serviceF, pathF); + } } - Type [] parTypes = new Type[] {typeof(Service), typeof(string), typeof(string)}; - object [] pars = new object[] {Service, this.introspector.InterfaceName, pathName}; + Type [] parTypes = new Type[] {typeof(Service), typeof(string)}; + object [] pars = new object[] {Service, pathName}; Type proxyType = typeB.CreateType(); @@ -247,7 +244,7 @@ namespace DBus // monodis. Note that in order for this to work you should copy // the client assembly as a dll file so that monodis can pick it // up. - //ProxyAssembly.Save("proxy.dll"); + ProxyAssembly.Save("proxy.dll"); ConstructorInfo constructor = proxyType.GetConstructor(parTypes); object instance = constructor.Invoke(pars); @@ -256,45 +253,41 @@ namespace DBus private ModuleBuilder ServiceModuleBuilder { - get - { - if (Service.module == null) { - Service.module = ProxyAssembly.DefineDynamicModule(Service.Name, "proxy.dll", true); - } - - return Service.module; + get { + if (Service.module == null) { + Service.module = ProxyAssembly.DefineDynamicModule(Service.Name, "proxy.dll", true); } + + return Service.module; + } } private Service Service { - get - { - return this.service; - } + get { + return this.service; + } } private string ProxyName { - get - { - return this.introspector.InterfaceName + ".Proxy"; - } + get { + return this.introspector.ToString() + ".Proxy"; + } } private AssemblyBuilder ProxyAssembly { - get - { - if (this.proxyAssembly == null){ - AssemblyName assemblyName = new AssemblyName(); - assemblyName.Name = "DBusProxy"; - this.proxyAssembly = Thread.GetDomain().DefineDynamicAssembly(assemblyName, - AssemblyBuilderAccess.RunAndSave); - } - - return this.proxyAssembly; + get { + if (this.proxyAssembly == null){ + AssemblyName assemblyName = new AssemblyName(); + assemblyName.Name = "DBusProxy"; + this.proxyAssembly = Thread.GetDomain().DefineDynamicAssembly(assemblyName, + AssemblyBuilderAccess.RunAndSave); } + + return this.proxyAssembly; + } } } } diff --git a/mono/Service.cs b/mono/Service.cs index a3c2a31f..39dd4f45 100644 --- a/mono/Service.cs +++ b/mono/Service.cs @@ -68,8 +68,8 @@ namespace DBus string pathName) { Handler handler = new Handler(handledObject, - pathName, - this); + pathName, + this); registeredHandlers.Add(handledObject, handler); } |