summaryrefslogtreecommitdiffstats
path: root/mono/Handler.cs
diff options
context:
space:
mode:
authorOwen Fraser-Green <owen@discobabe.net>2004-03-23 12:10:32 +0000
committerOwen Fraser-Green <owen@discobabe.net>2004-03-23 12:10:32 +0000
commitc916037773d7d3d8d37ca2c5a8899b7b728e377d (patch)
tree21c37372ab9795583e724e8459578b7fe0be330b /mono/Handler.cs
parent2195cf0dbde2ae26b5a684c6d914c1711f44c28d (diff)
First checkin of the Mono bindings.
Diffstat (limited to 'mono/Handler.cs')
-rw-r--r--mono/Handler.cs256
1 files changed, 256 insertions, 0 deletions
diff --git a/mono/Handler.cs b/mono/Handler.cs
new file mode 100644
index 00000000..d565b7ec
--- /dev/null
+++ b/mono/Handler.cs
@@ -0,0 +1,256 @@
+namespace DBus
+{
+ using System;
+ using System.Runtime.InteropServices;
+ using System.Diagnostics;
+ using System.Reflection;
+ using System.Collections;
+
+ internal class Handler
+ {
+ private string[] path = null;
+ 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;
+ private DBusHandleMessageFunction filterCalled;
+
+ internal delegate void DBusObjectPathUnregisterFunction(IntPtr rawConnection,
+ IntPtr userData);
+
+ internal delegate int DBusObjectPathMessageFunction(IntPtr rawConnection,
+ IntPtr rawMessage,
+ IntPtr userData);
+
+ internal delegate int DBusHandleMessageFunction(IntPtr rawConnection,
+ IntPtr rawMessage,
+ IntPtr userData);
+
+
+ private enum Result
+ {
+ Handled = 0,
+ NotYetHandled = 1,
+ NeedMemory = 2
+ }
+
+ [StructLayout (LayoutKind.Sequential)]
+ private struct DBusObjectPathVTable
+ {
+ public DBusObjectPathUnregisterFunction unregisterFunction;
+ public DBusObjectPathMessageFunction messageFunction;
+ public IntPtr padding1;
+ public IntPtr padding2;
+ public IntPtr padding3;
+ public IntPtr padding4;
+
+ public DBusObjectPathVTable(DBusObjectPathUnregisterFunction unregisterFunction,
+ DBusObjectPathMessageFunction messageFunction)
+ {
+ this.unregisterFunction = unregisterFunction;
+ this.messageFunction = messageFunction;
+ this.padding1 = IntPtr.Zero;
+ this.padding2 = IntPtr.Zero;
+ this.padding3 = IntPtr.Zero;
+ this.padding4 = IntPtr.Zero;
+ }
+ }
+
+ ~Handler()
+ {
+ if (Connection != null && Connection.RawConnection != IntPtr.Zero && path != null) {
+ dbus_connection_unregister_object_path(Connection.RawConnection,
+ Path);
+ }
+ }
+
+ public Handler(object handledObject,
+ string pathName,
+ Service service)
+ {
+ Service = service;
+ Connection = service.Connection;
+ HandledObject = handledObject;
+
+ // Strip the leading / off if there is one and get the path as an array
+ pathName = pathName.TrimStart('/');
+ this.path = pathName.Split('/');
+ this.pathName = "/" + pathName;
+
+ // Create the vTable and register the path
+ vTable = new DBusObjectPathVTable(new DBusObjectPathUnregisterFunction(Unregister_Called),
+ new DBusObjectPathMessageFunction(Message_Called));
+
+ if (!dbus_connection_register_object_path(Connection.RawConnection,
+ Path,
+ ref vTable,
+ IntPtr.Zero))
+ throw new OutOfMemoryException();
+
+ // Setup the filter function
+ this.filterCalled = new DBusHandleMessageFunction(Filter_Called);
+ if (!dbus_connection_add_filter(Connection.RawConnection,
+ this.filterCalled,
+ IntPtr.Zero,
+ IntPtr.Zero))
+ 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;
+ }
+
+ 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);
+ }
+ }
+ }
+
+ public int Filter_Called(IntPtr rawConnection,
+ IntPtr rawMessage,
+ IntPtr userData)
+ {
+ Message message = Message.Wrap(rawMessage, Service);
+
+ if (message.Type == Message.MessageType.Signal) {
+ Signal signal = (Signal) message;
+ } else if (message.Type == Message.MessageType.MethodCall) {
+ MethodCall methodCall = (MethodCall) message;
+ }
+
+ return (int) Result.NotYetHandled;
+ }
+
+ public void Unregister_Called(IntPtr rawConnection,
+ IntPtr userData)
+ {
+ System.Console.WriteLine("FIXME: Unregister called.");
+ }
+
+ private int Message_Called(IntPtr rawConnection,
+ IntPtr rawMessage,
+ IntPtr userData)
+ {
+ Message message = Message.Wrap(rawMessage, Service);
+
+ switch (message.Type) {
+ case Message.MessageType.Signal:
+ System.Console.WriteLine("FIXME: Signal called.");
+ break;
+ case Message.MessageType.MethodCall:
+ return (int) HandleMethod((MethodCall) message);
+ }
+
+ return (int) Result.NotYetHandled;
+ }
+
+ 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)) {
+ return Result.NotYetHandled;
+ }
+
+ // Got it!
+ MethodInfo method = (MethodInfo) handledMethods[key];
+
+ // Now call the method. FIXME: Error handling
+ object [] args = methodCall.Arguments.GetParameters(method);
+ object retVal = method.Invoke(this.handledObject, args);
+
+ // Create the reply and send it
+ MethodReturn methodReturn = new MethodReturn(methodCall);
+ methodReturn.Arguments.AppendResults(method, retVal, args);
+ methodReturn.Send();
+
+ return Result.Handled;
+ }
+
+ internal string[] Path
+ {
+ get
+ {
+ return path;
+ }
+ }
+
+ public string PathName
+ {
+ get
+ {
+ return pathName;
+ }
+ }
+
+ internal Connection Connection
+ {
+ get
+ {
+ return connection;
+ }
+
+ set
+ {
+ this.connection = value;
+ }
+ }
+
+ public Service Service
+ {
+ get
+ {
+ return service;
+ }
+
+ set
+ {
+ this.service = value;
+ }
+ }
+
+ [DllImport ("dbus-1")]
+ private extern static bool dbus_connection_register_object_path (IntPtr rawConnection, string[] path, ref DBusObjectPathVTable vTable, IntPtr userData);
+
+ [DllImport ("dbus-1")]
+ private extern static void dbus_connection_unregister_object_path (IntPtr rawConnection, string[] path);
+
+ [DllImport ("dbus-1")]
+ private extern static bool dbus_connection_add_filter(IntPtr rawConnection,
+ DBusHandleMessageFunction filter,
+ IntPtr userData,
+ IntPtr freeData);
+
+ }
+}