dbus/mono InterfaceProxy.cs, NONE, 1.1 Arguments.cs, 1.1, 1.2 Handler.cs, 1.1, 1.2 Introspector.cs, 1.1, 1.2 Makefile.am, 1.3, 1.4 Message.cs, 1.6, 1.7 ProxyBuilder.cs, 1.1, 1.2 Service.cs, 1.1, 1.2

Owen Fraser-Green ow3n at pdx.freedesktop.org
Tue Mar 23 10:07:50 PST 2004


Update of /cvs/dbus/dbus/mono
In directory pdx:/tmp/cvs-serv27858/mono

Modified Files:
	Arguments.cs Handler.cs Introspector.cs Makefile.am Message.cs 
	ProxyBuilder.cs Service.cs 
Added Files:
	InterfaceProxy.cs 
Log Message:
Added InterfaceProxy to Mono bindings to avoid having to generate a proxy for every registered object. Also added object_path functions to dbus-message.


--- NEW FILE: InterfaceProxy.cs ---
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;
      }
    }
  }
}

    

Index: Arguments.cs
===================================================================
RCS file: /cvs/dbus/dbus/mono/Arguments.cs,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -d -r1.1 -r1.2
--- a/Arguments.cs	23 Mar 2004 12:10:32 -0000	1.1
+++ b/Arguments.cs	23 Mar 2004 18:07:48 -0000	1.2
@@ -170,22 +170,6 @@
       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) 
     {

Index: Handler.cs
===================================================================
RCS file: /cvs/dbus/dbus/mono/Handler.cs,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -d -r1.1 -r1.2
--- a/Handler.cs	23 Mar 2004 12:10:32 -0000	1.1
+++ b/Handler.cs	23 Mar 2004 18:07:48 -0000	1.2
@@ -12,7 +12,6 @@
     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 @@
 	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 @@
     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);

Index: Introspector.cs
===================================================================
RCS file: /cvs/dbus/dbus/mono/Introspector.cs,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -d -r1.1 -r1.2
--- a/Introspector.cs	23 Mar 2004 12:10:32 -0000	1.1
+++ b/Introspector.cs	23 Mar 2004 18:07:48 -0000	1.2
@@ -10,97 +10,72 @@
   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();
     }
   }
 }

Index: Makefile.am
===================================================================
RCS file: /cvs/dbus/dbus/mono/Makefile.am,v
retrieving revision 1.3
retrieving revision 1.4
diff -u -d -r1.3 -r1.4
--- a/Makefile.am	23 Mar 2004 12:10:32 -0000	1.3
+++ b/Makefile.am	23 Mar 2004 18:07:48 -0000	1.4
@@ -12,6 +12,7 @@
 	Error.cs		\
 	Handler.cs		\
 	InterfaceAttribute.cs	\
+	InterfaceProxy.cs	\
 	Introspector.cs		\
 	Message.cs		\
 	MethodAttribute.cs	\

Index: Message.cs
===================================================================
RCS file: /cvs/dbus/dbus/mono/Message.cs,v
retrieving revision 1.6
retrieving revision 1.7
diff -u -d -r1.6 -r1.7
--- a/Message.cs	23 Mar 2004 12:10:32 -0000	1.6
+++ b/Message.cs	23 Mar 2004 18:07:48 -0000	1.7
@@ -35,6 +35,7 @@
     protected string pathName = null;
     protected string interfaceName = null;
     protected string name = null;    
+    private string key= null;
 
     protected Message()
     {
@@ -263,6 +264,17 @@
 	}
     }
 
+    public string Key
+    {
+      get {
+	if (this.key == null) {
+	  this.key = Name + " " + Arguments;
+	}
+	
+	return this.key;
+      }
+    }
+
     public Arguments Arguments
     {
       get 

Index: ProxyBuilder.cs
===================================================================
RCS file: /cvs/dbus/dbus/mono/ProxyBuilder.cs,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -d -r1.1 -r1.2
--- a/ProxyBuilder.cs	23 Mar 2004 12:10:32 -0000	1.1
+++ b/ProxyBuilder.cs	23 Mar 2004 18:07:48 -0000	1.2
@@ -50,13 +50,13 @@
       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 @@
       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 @@
       }
     }
     
-    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 @@
       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 @@
       
       // 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 @@
       // 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 @@
 
     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;
+      }
     }
   }
 }

Index: Service.cs
===================================================================
RCS file: /cvs/dbus/dbus/mono/Service.cs,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -d -r1.1 -r1.2
--- a/Service.cs	23 Mar 2004 12:10:32 -0000	1.1
+++ b/Service.cs	23 Mar 2004 18:07:48 -0000	1.2
@@ -68,8 +68,8 @@
 			       string pathName) 
     {
       Handler handler = new Handler(handledObject, 
-					    pathName, 
-					    this);
+				    pathName, 
+				    this);
       registeredHandlers.Add(handledObject, handler);
     }
 




More information about the dbus-commit mailing list