summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorHavoc Pennington <hp@redhat.com>2003-06-22 22:59:31 +0000
committerHavoc Pennington <hp@redhat.com>2003-06-22 22:59:31 +0000
commit1cc184b4a849619b56bed2be0e752fbc0fb75a29 (patch)
tree867409e28e08152147e095606e487793873dd51e
parent958805418359aca169cd363a4a3279f0fdab753c (diff)
2003-06-22 Havoc Pennington <hp@pobox.com>
* mono/Connection.cs, mono/DBus.cs, mono/Error.cs: Start wrapping more stuff.
-rw-r--r--ChangeLog5
-rw-r--r--mono/Connection.cs123
-rw-r--r--mono/DBus.cs13
-rw-r--r--mono/Error.cs29
-rw-r--r--mono/Makefile.am6
-rw-r--r--mono/Message.cs19
-rw-r--r--mono/Test.cs3
7 files changed, 186 insertions, 12 deletions
diff --git a/ChangeLog b/ChangeLog
index 7e712582..06deccd2 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,10 @@
2003-06-22 Havoc Pennington <hp@pobox.com>
+ * mono/Connection.cs, mono/DBus.cs, mono/Error.cs:
+ Start wrapping more stuff.
+
+2003-06-22 Havoc Pennington <hp@pobox.com>
+
* mono/Message.cs: implement Message.Wrap() that ensures we only
have a single C# wrapper per DBusMessage, assuming it works which
it probably doesn't.
diff --git a/mono/Connection.cs b/mono/Connection.cs
new file mode 100644
index 00000000..f0d34eec
--- /dev/null
+++ b/mono/Connection.cs
@@ -0,0 +1,123 @@
+namespace DBus {
+
+ using System;
+ using System.Runtime.InteropServices;
+ using System.Diagnostics;
+
+ public class Connection {
+
+ public Connection (string address) {
+ // the assignment bumps the refcount
+ Error error = new Error ();
+ error.Init ();
+ raw = dbus_connection_open (address, ref error);
+ if (raw != (IntPtr) 0) {
+ dbus_connection_unref (raw);
+ } else {
+ Exception e = new Exception (ref error);
+ error.Free ();
+ throw e;
+ }
+ }
+
+ public static Connection Wrap (IntPtr ptr) {
+ IntPtr gch_ptr;
+
+ gch_ptr = dbus_connection_get_data (ptr, wrapper_slot);
+ if (gch_ptr != (IntPtr) 0) {
+ return (DBus.Connection) ((GCHandle)gch_ptr).Target;
+ } else {
+ return new Connection (ptr);
+ }
+ }
+
+ // surely there's a convention for this pattern with the property
+ // and the real member
+ IntPtr raw_;
+ IntPtr raw {
+ get {
+ return raw_;
+ }
+ set {
+ if (value == raw_)
+ return;
+
+ if (raw_ != (IntPtr) 0) {
+ IntPtr gch_ptr;
+
+ gch_ptr = dbus_connection_get_data (raw_,
+ wrapper_slot);
+ Debug.Assert (gch_ptr != (IntPtr) 0);
+
+ dbus_connection_set_data (raw_, wrapper_slot,
+ (IntPtr) 0, (IntPtr) 0);
+
+ ((GCHandle) gch_ptr).Free ();
+
+ dbus_connection_unref (raw_);
+ }
+
+ raw_ = value;
+
+ if (raw_ != (IntPtr) 0) {
+ GCHandle gch;
+
+ dbus_connection_ref (raw_);
+
+ // We store a weak reference to the C# object on the C object
+ gch = GCHandle.Alloc (this, GCHandleType.WeakTrackResurrection);
+
+ dbus_connection_set_data (raw_, wrapper_slot,
+ (IntPtr) gch, (IntPtr) 0);
+ }
+ }
+ }
+
+ ~Connection () {
+ raw = (IntPtr) 0; // free the native object
+ }
+
+ Connection (IntPtr r) {
+ raw = r;
+ }
+
+ // static constructor runs before any methods
+ static Connection () {
+ Debug.Assert (wrapper_slot == -1);
+
+ if (!dbus_connection_allocate_data_slot (ref wrapper_slot))
+ throw new OutOfMemoryException ();
+
+ Debug.Assert (wrapper_slot >= 0);
+ }
+
+ // slot used to store the C# object on the C object
+ static int wrapper_slot = -1;
+
+ [DllImport (DBus.Internals.Libname, EntryPoint="dbus_connection_open")]
+ private extern static IntPtr dbus_connection_open (string address,
+ ref Error error);
+
+ [DllImport (DBus.Internals.Libname, EntryPoint="dbus_connection_unref")]
+ private extern static void dbus_connection_unref (IntPtr ptr);
+
+ [DllImport (DBus.Internals.Libname, EntryPoint="dbus_connection_ref")]
+ private extern static void dbus_connection_ref (IntPtr ptr);
+
+ [DllImport (DBus.Internals.Libname, EntryPoint="dbus_connection_allocate_data_slot")]
+ private extern static bool dbus_connection_allocate_data_slot (ref int slot);
+
+ [DllImport (DBus.Internals.Libname, EntryPoint="dbus_connection_free_data_slot")]
+ private extern static void dbus_connection_free_data_slot (ref int slot);
+
+ [DllImport (DBus.Internals.Libname, EntryPoint="dbus_connection_set_data")]
+ private extern static bool dbus_connection_set_data (IntPtr ptr,
+ int slot,
+ IntPtr data,
+ IntPtr free_data_func);
+
+ [DllImport (DBus.Internals.Libname, EntryPoint="dbus_connection_get_data")]
+ private extern static IntPtr dbus_connection_get_data (IntPtr ptr,
+ int slot);
+ }
+}
diff --git a/mono/DBus.cs b/mono/DBus.cs
new file mode 100644
index 00000000..1032792a
--- /dev/null
+++ b/mono/DBus.cs
@@ -0,0 +1,13 @@
+namespace DBus {
+
+ using System;
+
+ public class Exception : ApplicationException {
+ internal Exception (ref Error error)
+ : base (Runtime.InteropServices.Marshal.PtrToStringAnsi (error.message)) { }
+ }
+
+ public class Internals {
+ public const string Libname = "libdbus-1.so.0";
+ }
+}
diff --git a/mono/Error.cs b/mono/Error.cs
new file mode 100644
index 00000000..95c0193b
--- /dev/null
+++ b/mono/Error.cs
@@ -0,0 +1,29 @@
+namespace DBus {
+
+ using System;
+ using System.Runtime.InteropServices;
+
+ // FIXME add code to verify that size of DBus.Error
+ // matches the C code.
+
+ [StructLayout (LayoutKind.Sequential)]
+ internal struct Error {
+ internal IntPtr name;
+ internal IntPtr message;
+ private int dummies;
+ private IntPtr padding1;
+
+ internal void Init () {
+ dbus_error_init (ref this);
+ }
+
+ internal void Free () {
+ dbus_error_free (ref this);
+ }
+
+ [DllImport (DBus.Internals.Libname, EntryPoint="dbus_error_init")]
+ private extern static void dbus_error_init (ref Error error);
+ [DllImport (DBus.Internals.Libname, EntryPoint="dbus_error_free")]
+ private extern static void dbus_error_free (ref Error error);
+ }
+}
diff --git a/mono/Makefile.am b/mono/Makefile.am
index d81bcc28..efd61b4b 100644
--- a/mono/Makefile.am
+++ b/mono/Makefile.am
@@ -3,16 +3,16 @@ DESTDIR=
DLLS=dbus-sharp.dll
NOINST_EXES=test-dbus-sharp
-DBUS_SHARP_FILES=Message.cs
+DBUS_SHARP_FILES= DBus.cs Message.cs Connection.cs Error.cs
TEST_DBUS_SHARP_FILES=Test.cs
all: $(DLLS) $(NOINST_EXES)
dbus-sharp.dll: $(DBUS_SHARP_FILES)
- $(MCS) $(MCSFLAGS) --unsafe --target library -o dbus-sharp.dll --recurse '$(DBUS_SHARP_FILES)'
+ $(MCS) $(MCSFLAGS) --unsafe --target library -o dbus-sharp.dll $(DBUS_SHARP_FILES)
test-dbus-sharp: $(TEST_DBUS_SHARP_FILES)
- $(MCS) $(MCSFLAGS) --unsafe --target exe -L . -r dbus-sharp.dll -o test-dbus-sharp --recurse '$(TEST_DBUS_SHARP_FILES)'
+ $(MCS) $(MCSFLAGS) --unsafe --target exe -L . -r dbus-sharp.dll -o test-dbus-sharp $(TEST_DBUS_SHARP_FILES)
clean:
rm -f $(DLLS) $(NOINST_EXES)
diff --git a/mono/Message.cs b/mono/Message.cs
index 0e41c9ec..a6d3c092 100644
--- a/mono/Message.cs
+++ b/mono/Message.cs
@@ -10,6 +10,8 @@ namespace DBus {
string dest_service) {
// the assignment bumps the refcount
raw = dbus_message_new (name, dest_service);
+ if (raw == (IntPtr) 0)
+ throw new OutOfMemoryException ();
dbus_message_unref (raw);
}
@@ -92,34 +94,33 @@ namespace DBus {
// slot used to store the C# object on the C object
static int wrapper_slot = -1;
- const string libname = "libdbus-1.so.0";
- [DllImport (libname, EntryPoint="dbus_message_new")]
+ [DllImport (DBus.Internals.Libname, EntryPoint="dbus_message_new")]
private extern static IntPtr dbus_message_new (string name,
string dest_service);
- [DllImport (libname, EntryPoint="dbus_message_unref")]
+ [DllImport (DBus.Internals.Libname, EntryPoint="dbus_message_unref")]
private extern static void dbus_message_unref (IntPtr ptr);
- [DllImport (libname, EntryPoint="dbus_message_ref")]
+ [DllImport (DBus.Internals.Libname, EntryPoint="dbus_message_ref")]
private extern static void dbus_message_ref (IntPtr ptr);
- [DllImport (libname, EntryPoint="dbus_message_get_name")]
+ [DllImport (DBus.Internals.Libname, EntryPoint="dbus_message_get_name")]
private extern static string dbus_message_get_name (IntPtr ptr);
- [DllImport (libname, EntryPoint="dbus_message_allocate_data_slot")]
+ [DllImport (DBus.Internals.Libname, EntryPoint="dbus_message_allocate_data_slot")]
private extern static bool dbus_message_allocate_data_slot (ref int slot);
- [DllImport (libname, EntryPoint="dbus_message_free_data_slot")]
+ [DllImport (DBus.Internals.Libname, EntryPoint="dbus_message_free_data_slot")]
private extern static void dbus_message_free_data_slot (ref int slot);
- [DllImport (libname, EntryPoint="dbus_message_set_data")]
+ [DllImport (DBus.Internals.Libname, EntryPoint="dbus_message_set_data")]
private extern static bool dbus_message_set_data (IntPtr ptr,
int slot,
IntPtr data,
IntPtr free_data_func);
- [DllImport (libname, EntryPoint="dbus_message_get_data")]
+ [DllImport (DBus.Internals.Libname, EntryPoint="dbus_message_get_data")]
private extern static IntPtr dbus_message_get_data (IntPtr ptr,
int slot);
}
diff --git a/mono/Test.cs b/mono/Test.cs
index ffe7d0a6..e07504d7 100644
--- a/mono/Test.cs
+++ b/mono/Test.cs
@@ -4,6 +4,9 @@ using System;
class Test {
static void Main() {
DBus.Message m;
+ DBus.Connection c;
+
+ c = new DBus.Connection ("unix:path=/tmp/foobar");
m = new DBus.Message ("org.freedesktop.Foo", null);