Modified to support char type.
[platform/upstream/dbus.git] / mono / Connection.cs
1 namespace DBus 
2 {
3   
4   using System;
5   using System.Runtime.InteropServices;
6   using System.Diagnostics;
7   using System.Reflection;
8   using System.IO;
9   using System.Collections;
10   
11   public class Connection 
12   {
13     /// <summary>
14     /// A pointer to the underlying Connection structure
15     /// </summary>
16     private IntPtr rawConnection;
17     
18     /// <summary>
19     /// The current slot number
20     /// </summary>
21     private static int slot = -1;
22     
23     private int timeout = -1;
24
25     internal Connection(IntPtr rawConnection)
26     {
27       RawConnection = rawConnection;
28     }
29     
30     public Connection(string address)
31     {
32       // the assignment bumps the refcount
33       Error error = new Error();
34       error.Init();
35       RawConnection = dbus_connection_open(address, ref error);
36       if (RawConnection != IntPtr.Zero) {
37         dbus_connection_unref(RawConnection);
38       } else {
39         throw new DBusException(error);
40       }
41
42       SetupWithMain();
43     }
44
45     public void SetupWithMain() 
46     {      
47       dbus_connection_setup_with_g_main(RawConnection, IntPtr.Zero);
48     }
49     
50     ~Connection () 
51     {
52       if (RawConnection != IntPtr.Zero) 
53         {
54           dbus_connection_disconnect(rawConnection);
55         }
56       RawConnection = IntPtr.Zero; // free the native object
57     }
58     
59     internal static Connection Wrap(IntPtr rawConnection) 
60     {
61       if (slot > -1) {
62         // If we already have a Connection object associated with this rawConnection then return it
63         IntPtr rawThis = dbus_connection_get_data (rawConnection, slot);
64         return (DBus.Connection) ((GCHandle)rawThis).Target;
65       } 
66       else 
67         {
68           // If it doesn't exist then create a new connection around it
69           return new Connection(rawConnection);
70         }
71     }
72
73     public int Timeout
74     {
75       get
76         {
77           return this.timeout;
78         }
79       set
80         {
81           this.timeout = value;
82         }
83     }
84     
85     private int Slot
86     {
87       get 
88         {
89           if (slot == -1) 
90             {
91               // We need to initialize the slot
92               if (!dbus_connection_allocate_data_slot (ref slot))
93                 throw new OutOfMemoryException ();
94               
95               Debug.Assert (slot >= 0);
96             }
97           
98           return slot;
99         }
100     }
101     
102     internal IntPtr RawConnection 
103     {
104       get 
105         {
106           return rawConnection;
107         }
108       set 
109         {
110           if (value == rawConnection)
111             return;
112           
113           if (rawConnection != IntPtr.Zero) 
114             {
115               // Get the reference to this
116               IntPtr rawThis = dbus_connection_get_data (rawConnection, Slot);
117               Debug.Assert (rawThis != IntPtr.Zero);
118               
119               // Blank over the reference
120               dbus_connection_set_data (rawConnection, Slot, IntPtr.Zero, IntPtr.Zero);
121               
122               // Free the reference
123               ((GCHandle) rawThis).Free();
124               
125               // Unref the connection
126               dbus_connection_unref(rawConnection);
127             }
128           
129           this.rawConnection = value;
130           
131           if (rawConnection != IntPtr.Zero) 
132             {
133               GCHandle rawThis;
134               
135               dbus_connection_ref (rawConnection);
136               
137               // We store a weak reference to the C# object on the C object
138               rawThis = GCHandle.Alloc (this, GCHandleType.WeakTrackResurrection);
139               
140               dbus_connection_set_data(rawConnection, Slot, (IntPtr) rawThis, IntPtr.Zero);
141             }
142         }
143     }
144
145     [DllImport("dbus-glib-1")]
146     private extern static void dbus_connection_setup_with_g_main(IntPtr rawConnection,
147                                                              IntPtr rawContext);
148     
149     [DllImport ("dbus-1")]
150     private extern static IntPtr dbus_connection_open (string address, ref Error error);
151     
152     [DllImport ("dbus-1")]
153     private extern static void dbus_connection_unref (IntPtr ptr);
154     
155     [DllImport ("dbus-1")]
156     private extern static void dbus_connection_ref (IntPtr ptr);
157     
158     [DllImport ("dbus-1")]
159     private extern static bool dbus_connection_allocate_data_slot (ref int slot);
160     
161     [DllImport ("dbus-1")]
162     private extern static void dbus_connection_free_data_slot (ref int slot);
163     
164     [DllImport ("dbus-1")]
165     private extern static bool dbus_connection_set_data (IntPtr ptr,
166                                                          int    slot,
167                                                          IntPtr data,
168                                                          IntPtr free_data_func);
169     
170     [DllImport ("dbus-1")]
171     private extern static void dbus_connection_flush (IntPtr  ptr);
172     
173     [DllImport ("dbus-1")]
174     private extern static IntPtr dbus_connection_get_data (IntPtr ptr,
175                                                            int    slot);
176     
177     [DllImport ("dbus-1")]
178     private extern static void dbus_connection_disconnect (IntPtr ptr);
179   }
180 }