Main Page | Modules | Namespace List | Class Hierarchy | Data Structures | Directories | File List | Namespace Members | Data Fields | Related Pages

Message.cs

00001 namespace DBus 
00002 {
00003   
00004   using System;
00005   using System.Runtime.InteropServices;
00006   using System.Diagnostics;
00007   using System.Collections;
00008   
00009   public class Message : IDisposable
00010   {
00011     private static Stack stack = new Stack ();
00012           
00013     static public Message Current {
00014       get 
00015         {
00016           return stack.Count > 0 ? (Message) stack.Peek () : null;
00017         }
00018     }
00019 
00020     static internal void Push (Message message)
00021     {
00022       stack.Push (message);
00023     }
00024 
00025     static internal void Pop ()
00026     {
00027       stack.Pop ();
00028     }
00029           
00030     
00034     private IntPtr rawMessage;
00035     
00039     private static int slot = -1;
00040     
00041     // Keep in sync with C
00042     public enum MessageType 
00043     {
00044       Invalid = 0,
00045       MethodCall = 1,
00046       MethodReturn = 2,
00047       Error = 3,
00048       Signal = 4
00049     }
00050 
00051     private Arguments arguments = null;
00052 
00053     protected Service service = null;
00054     protected string pathName = null;
00055     protected string interfaceName = null;
00056     protected string name = null;    
00057     private string key= null;
00058 
00059     protected Message()
00060     {
00061       // An empty constructor for the sake of sub-classes which know how to construct theirselves.
00062     }
00063     
00064     protected Message(IntPtr rawMessage, Service service)
00065     {
00066       RawMessage = rawMessage;
00067       this.service = service;
00068     }
00069     
00070     protected Message(MessageType messageType) 
00071     {
00072       // the assignment bumps the refcount
00073       RawMessage = dbus_message_new((int) messageType);
00074       
00075       if (RawMessage == IntPtr.Zero) {
00076         throw new OutOfMemoryException();
00077       }
00078       
00079       dbus_message_unref(RawMessage);
00080     }
00081     
00082     protected Message(MessageType messageType, Service service) : this(messageType) 
00083     {
00084       this.service = service;
00085     }
00086 
00087     public void Dispose() 
00088     {
00089       Dispose(true);
00090       GC.SuppressFinalize(this);
00091     }
00092     
00093     public void Dispose (bool disposing) 
00094     {
00095       if (disposing) {
00096         if (this.arguments != null)
00097           this.arguments.Dispose ();
00098       }
00099 
00100       RawMessage = IntPtr.Zero; // free the native object
00101     }     
00102 
00103     ~Message() 
00104     {
00105       Dispose (false);
00106     }
00107     
00108     public static Message Wrap(IntPtr rawMessage, Service service) 
00109     {
00110       if (slot > -1) {
00111         // If we already have a Message object associated with this rawMessage then return it
00112         IntPtr rawThis = dbus_message_get_data(rawMessage, slot);
00113         if (rawThis != IntPtr.Zero)
00114           return (DBus.Message) ((GCHandle)rawThis).Target;
00115       } 
00116       // If it doesn't exist then create a new Message around it
00117       Message message = null;
00118       MessageType messageType = (MessageType) dbus_message_get_type(rawMessage);
00119       
00120       switch (messageType) {
00121       case MessageType.Signal:
00122         message = new Signal(rawMessage, service);
00123         break;
00124       case MessageType.MethodCall:
00125         message = new MethodCall(rawMessage, service);
00126         break;
00127       case MessageType.MethodReturn:
00128         message = new MethodReturn(rawMessage, service);
00129         break;
00130       case MessageType.Error:
00131         message = new ErrorMessage(rawMessage, service);
00132         break;
00133       default:
00134         throw new ApplicationException("Unknown message type to wrap: " + messageType);
00135       }
00136 
00137       return message;
00138     }
00139     
00140     internal IntPtr RawMessage 
00141     {
00142       get 
00143         {
00144           return rawMessage;
00145         }
00146       set 
00147         {
00148           if (value == rawMessage) 
00149             return;
00150           
00151           if (rawMessage != IntPtr.Zero) 
00152             {
00153               // Get the reference to this
00154               IntPtr rawThis = dbus_message_get_data(rawMessage, Slot);
00155               Debug.Assert (rawThis != IntPtr.Zero);
00156               
00157               // Blank over the reference
00158               dbus_message_set_data(rawMessage, Slot, IntPtr.Zero, IntPtr.Zero);
00159               
00160               // Free the reference
00161               ((GCHandle) rawThis).Free();
00162               
00163               // Unref the connection
00164               dbus_message_unref(rawMessage);
00165             }
00166           
00167           this.rawMessage = value;
00168           
00169           if (rawMessage != IntPtr.Zero) 
00170             {
00171               GCHandle rawThis;
00172               
00173               dbus_message_ref(rawMessage);
00174               
00175               // We store a weak reference to the C# object on the C object
00176               rawThis = GCHandle.Alloc(this, GCHandleType.WeakTrackResurrection);
00177               
00178               dbus_message_set_data(rawMessage, Slot, (IntPtr) rawThis, IntPtr.Zero);
00179             }
00180         }
00181     }
00182     
00183     public void Send(ref int serial) 
00184     {
00185       if (!dbus_connection_send (Service.Connection.RawConnection, RawMessage, ref serial))
00186         throw new OutOfMemoryException ();
00187 
00188       Service.Connection.Flush();
00189     }
00190     
00191     public void Send() 
00192     {
00193       int ignored = 0;
00194       Send(ref ignored);
00195     }
00196 
00197     public void SendWithReply() 
00198     {
00199       IntPtr rawPendingCall = IntPtr.Zero;
00200       
00201       if (!dbus_connection_send_with_reply (Service.Connection.RawConnection, RawMessage, rawPendingCall, Service.Connection.Timeout))
00202         throw new OutOfMemoryException();
00203     }
00204      
00205     public MethodReturn SendWithReplyAndBlock()
00206     {
00207       Error error = new Error();
00208       error.Init();
00209 
00210       IntPtr rawMessage = dbus_connection_send_with_reply_and_block(Service.Connection.RawConnection, 
00211                                                                     RawMessage, 
00212                                                                     Service.Connection.Timeout, 
00213                                                                     ref error);
00214 
00215       if (rawMessage != IntPtr.Zero) {
00216         MethodReturn methodReturn = new MethodReturn(rawMessage, Service);
00217         // Ownership of a ref is passed onto us from
00218         // dbus_connection_send_with_reply_and_block().  It gets reffed as
00219         // a result of being passed into the MethodReturn ctor, so unref
00220         // the extra one here.
00221         dbus_message_unref (rawMessage);
00222 
00223         return methodReturn;
00224       } else {
00225         throw new DBusException(error);
00226       }
00227     }
00228 
00229     public MessageType Type
00230     {
00231       get 
00232         {
00233           return (MessageType) dbus_message_get_type(RawMessage);
00234         }
00235     }
00236     
00237     public Service Service
00238     {
00239       set 
00240         {
00241           if (this.service != null && (value.Name != this.service.Name)) {
00242             if (!dbus_message_set_destination(RawMessage, value.Name)) {
00243               throw new OutOfMemoryException();
00244             }
00245           }
00246           
00247           this.service = value;
00248         }
00249       get 
00250         {
00251           return this.service;
00252         }
00253     }
00254     
00255     protected virtual string PathName
00256     {
00257       set 
00258         {
00259           if (value != this.pathName) 
00260             {
00261               if (!dbus_message_set_path(RawMessage, value)) {
00262                 throw new OutOfMemoryException();
00263               }
00264               
00265               this.pathName = value;
00266             }
00267         }
00268       get 
00269         {
00270           if (this.pathName == null) {
00271             this.pathName = Marshal.PtrToStringAnsi(dbus_message_get_path(RawMessage));
00272           }
00273           
00274           return this.pathName;
00275         }
00276     }
00277     
00278     protected virtual string InterfaceName
00279     {
00280       set 
00281         {
00282           if (value != this.interfaceName)
00283             {
00284               dbus_message_set_interface (RawMessage, value);
00285               this.interfaceName = value;
00286             }
00287         }
00288       get 
00289         {
00290           if (this.interfaceName == null) {
00291             this.interfaceName = Marshal.PtrToStringAnsi(dbus_message_get_interface(RawMessage));
00292           }
00293 
00294           return this.interfaceName;
00295         }
00296     }
00297     
00298     protected virtual string Name
00299     {
00300       set {
00301         if (value != this.name) {
00302           dbus_message_set_member(RawMessage, value);
00303           this.name = value;
00304         }
00305       }
00306       get {
00307         if (this.name == null) {
00308           this.name = Marshal.PtrToStringAnsi(dbus_message_get_member(RawMessage));
00309         }
00310 
00311         return this.name;
00312       }
00313     }
00314 
00315     public string Key
00316     {
00317       get {
00318         if (this.key == null) {
00319           this.key = Name + " " + Arguments;
00320         }
00321         
00322         return this.key;
00323       }
00324     }
00325 
00326     public Arguments Arguments
00327     {
00328       get 
00329         {
00330           if (this.arguments == null) {
00331             this.arguments = new Arguments(this);
00332           }
00333           
00334           return this.arguments;
00335         }
00336     }
00337 
00338     public string Sender 
00339     {
00340       get
00341         {
00342           return Marshal.PtrToStringAnsi(dbus_message_get_sender(RawMessage));
00343         }
00344     }
00345 
00346     public string Destination
00347     {
00348       get
00349         {
00350           return Marshal.PtrToStringAnsi(dbus_message_get_destination(RawMessage));
00351         }
00352     }
00353             
00354     protected int Slot
00355     {
00356       get 
00357         {
00358           if (slot == -1) 
00359             {
00360               // We need to initialize the slot
00361               if (!dbus_message_allocate_data_slot (ref slot))
00362                 throw new OutOfMemoryException ();
00363               
00364               Debug.Assert (slot >= 0);
00365             }
00366           
00367           return slot;
00368         }
00369     }
00370     
00371     [DllImport ("dbus-1", EntryPoint="dbus_message_new")]
00372     protected extern static IntPtr dbus_message_new (int messageType);
00373     
00374     [DllImport ("dbus-1", EntryPoint="dbus_message_unref")]
00375     protected extern static void dbus_message_unref (IntPtr ptr);
00376     
00377     [DllImport ("dbus-1", EntryPoint="dbus_message_ref")]
00378     protected extern static void dbus_message_ref (IntPtr ptr);
00379     
00380     [DllImport ("dbus-1", EntryPoint="dbus_message_allocate_data_slot")]
00381     protected extern static bool dbus_message_allocate_data_slot (ref int slot);
00382     
00383     [DllImport ("dbus-1", EntryPoint="dbus_message_free_data_slot")]
00384     protected extern static void dbus_message_free_data_slot (ref int slot);
00385     
00386     [DllImport ("dbus-1", EntryPoint="dbus_message_set_data")]
00387     protected extern static bool dbus_message_set_data (IntPtr ptr,
00388                                                         int    slot,
00389                                                         IntPtr data,
00390                                                         IntPtr free_data_func);
00391     
00392     [DllImport ("dbus-1", EntryPoint="dbus_message_get_data")]
00393     protected extern static IntPtr dbus_message_get_data (IntPtr ptr,
00394                                                           int    slot);
00395     
00396     [DllImport ("dbus-1", EntryPoint="dbus_connection_send")]
00397     private extern static bool dbus_connection_send (IntPtr  ptr,
00398                                                      IntPtr  message,
00399                                                      ref int client_serial);
00400 
00401     [DllImport ("dbus-1", EntryPoint="dbus_connection_send_with_reply")]
00402     private extern static bool dbus_connection_send_with_reply (IntPtr rawConnection, IntPtr rawMessage, IntPtr rawPendingCall, int timeout);
00403 
00404     [DllImport ("dbus-1", EntryPoint="dbus_connection_send_with_reply_and_block")]
00405     private extern static IntPtr dbus_connection_send_with_reply_and_block (IntPtr rawConnection, IntPtr  message, int timeout, ref Error error);
00406 
00407     [DllImport("dbus-1")]
00408     private extern static int dbus_message_get_type(IntPtr rawMessage);
00409 
00410     [DllImport("dbus-1")]
00411     private extern static bool dbus_message_set_path(IntPtr rawMessage, string pathName);
00412 
00413     [DllImport("dbus-1")]
00414     private extern static IntPtr dbus_message_get_path(IntPtr rawMessage);
00415     
00416     [DllImport("dbus-1")]
00417     private extern static bool dbus_message_set_interface (IntPtr rawMessage, string interfaceName);
00418 
00419     [DllImport("dbus-1")]
00420     private extern static IntPtr dbus_message_get_interface(IntPtr rawMessage);
00421     
00422     [DllImport("dbus-1")]
00423     private extern static bool dbus_message_set_member(IntPtr rawMessage, string name);
00424 
00425     [DllImport("dbus-1")]
00426     private extern static IntPtr dbus_message_get_member(IntPtr rawMessage);
00427 
00428     [DllImport("dbus-1")]
00429     private extern static bool dbus_message_set_destination(IntPtr rawMessage, string serviceName);
00430 
00431     [DllImport("dbus-1")]
00432     private extern static IntPtr dbus_message_get_destination(IntPtr rawMessage);
00433 
00434     [DllImport("dbus-1")]
00435     private extern static IntPtr dbus_message_get_sender(IntPtr rawMessage);
00436   }
00437 }

Generated on Tue Sep 13 01:28:08 2005 for D-BUS by  doxygen 1.4.4