summaryrefslogtreecommitdiffstats
path: root/mono
diff options
context:
space:
mode:
authorOwen Fraser-Green <owen@discobabe.net>2004-03-23 18:07:48 +0000
committerOwen Fraser-Green <owen@discobabe.net>2004-03-23 18:07:48 +0000
commit632d54e0dbf5e405258be7afffbaa48942c06cbc (patch)
tree0b3495f8a0753d427078a90e585dc53a2287200d /mono
parent0a673a8cd751d9eae14f3f5d0eeebf749b07bf09 (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.cs16
-rw-r--r--mono/Handler.cs56
-rw-r--r--mono/InterfaceProxy.cs86
-rw-r--r--mono/Introspector.cs127
-rw-r--r--mono/Makefile.am1
-rw-r--r--mono/Message.cs12
-rw-r--r--mono/ProxyBuilder.cs81
-rw-r--r--mono/Service.cs4
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);
}