diff options
| -rw-r--r-- | ChangeLog | 5 | ||||
| -rw-r--r-- | mono/Connection.cs | 123 | ||||
| -rw-r--r-- | mono/DBus.cs | 13 | ||||
| -rw-r--r-- | mono/Error.cs | 29 | ||||
| -rw-r--r-- | mono/Makefile.am | 6 | ||||
| -rw-r--r-- | mono/Message.cs | 19 | ||||
| -rw-r--r-- | mono/Test.cs | 3 | 
7 files changed, 186 insertions, 12 deletions
| @@ -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); | 
