1 use std::borrow::Cow;
2 use std::{fmt, mem, ptr, ops};
3 use super::{ffi, Error, MessageType, Signature, libc, to_c_str, c_str_to_slice, init_dbus};
4 use super::{BusName, Path, Interface, Member, ErrorName, Connection, SignalArgs};
5 use std::os::unix::io::{RawFd, AsRawFd};
6 use std::ffi::CStr;
7 use std::os::raw::{c_void, c_char, c_int};
8 
9 use super::arg::{Append, IterAppend, Get, Iter, Arg, RefArg, TypeMismatchError};
10 
11 #[derive(Debug,Copy,Clone)]
12 /// Errors that can happen when creating a MessageItem::Array.
13 pub enum ArrayError {
14     /// The array is empty.
15     EmptyArray,
16     /// The array is composed of different element types.
17     DifferentElementTypes,
18     /// The supplied signature is not a valid array signature
19     InvalidSignature,
20 }
21 
new_dbus_message_iter() -> ffi::DBusMessageIter22 fn new_dbus_message_iter() -> ffi::DBusMessageIter { unsafe { mem::zeroed() }}
23 
24 
25 /// An RAII wrapper around Fd to ensure that file descriptor is closed
26 /// when the scope ends.
27 #[derive(Debug, PartialEq, PartialOrd)]
28 pub struct OwnedFd {
29     fd: RawFd
30 }
31 
32 impl OwnedFd {
33     /// Create a new OwnedFd from a RawFd.
new(fd: RawFd) -> OwnedFd34     pub fn new(fd: RawFd) -> OwnedFd {
35         OwnedFd { fd: fd }
36     }
37 
38     /// Convert an OwnedFD back into a RawFd.
into_fd(self) -> RawFd39     pub fn into_fd(self) -> RawFd {
40         let s = self.fd;
41         ::std::mem::forget(self);
42         s
43     }
44 }
45 
46 impl Drop for OwnedFd {
drop(&mut self)47     fn drop(&mut self) {
48         unsafe { libc::close(self.fd); }
49     }
50 }
51 
52 impl Clone for OwnedFd {
clone(&self) -> OwnedFd53     fn clone(&self) -> OwnedFd {
54         OwnedFd::new(unsafe { libc::dup(self.fd) } ) // FIXME: handle errors
55     }
56 }
57 
58 impl AsRawFd for OwnedFd {
as_raw_fd(&self) -> RawFd59     fn as_raw_fd(&self) -> RawFd {
60         self.fd
61     }
62 }
63 
64 #[derive(Debug, Clone, PartialEq, PartialOrd)]
65 /// An array of MessageItem where every MessageItem is of the same type.
66 pub struct MessageItemArray {
67     v: Vec<MessageItem>,
68     // signature includes the "a"!
69     sig: Signature<'static>,
70 }
71 
72 impl MessageItemArray {
73     /// Creates a new array where every element has the supplied signature.
74     ///
75     /// Signature is the full array signature, not the signature of the element.
new(v: Vec<MessageItem>, sig: Signature<'static>) -> Result<MessageItemArray, ArrayError>76     pub fn new(v: Vec<MessageItem>, sig: Signature<'static>) -> Result<MessageItemArray, ArrayError> {
77         let a = MessageItemArray {v: v, sig: sig };
78         if a.sig.as_bytes()[0] != ffi::DBUS_TYPE_ARRAY as u8 { return Err(ArrayError::InvalidSignature) }
79         {
80             let esig = a.element_signature();
81             for i in &a.v {
82                 let b = if let MessageItem::DictEntry(ref k, ref v) = *i {
83                      let s = format!("{{{}{}}}", k.signature(), v.signature());
84                      s.as_bytes() == esig.to_bytes()
85                 } else {
86                      i.signature().as_cstr() == esig
87                 };
88                 if !b { return Err(ArrayError::DifferentElementTypes) }
89             }
90         }
91         Ok(a)
92     }
93 
element_signature(&self) -> &CStr94     fn element_signature(&self) -> &CStr {
95         let z = &self.sig.as_cstr().to_bytes_with_nul()[1..];
96         unsafe { CStr::from_bytes_with_nul_unchecked(z) }
97     }
98 
make_sig(m: &MessageItem) -> Signature<'static>99     fn make_sig(m: &MessageItem) -> Signature<'static> {
100         if let MessageItem::DictEntry(ref k, ref v) = *m {
101             Signature::new(format!("a{{{}{}}}", k.signature(), v.signature())).unwrap()
102         } else {
103             Signature::new(format!("a{}", m.signature())).unwrap()
104         }
105     }
106 
107     /// Signature of array (full array signature)
signature(&self) -> &Signature<'static>108     pub fn signature(&self) -> &Signature<'static> { &self.sig }
109 
110     /// Consumes the MessageItemArray in order to allow you to modify the individual items of the array.
into_vec(self) -> Vec<MessageItem>111     pub fn into_vec(self) -> Vec<MessageItem> { self.v }
112 }
113 
114 impl ops::Deref for MessageItemArray {
115     type Target = [MessageItem];
deref(&self) -> &Self::Target116     fn deref(&self) -> &Self::Target { &self.v }
117 }
118 
119 
120 /// MessageItem - used as parameters and return values from
121 /// method calls, or as data added to a signal (old, enum version).
122 ///
123 /// Note that the newer generic design (see `arg` module) is both faster
124 /// and less error prone than MessageItem, and should be your first hand choice
125 /// whenever applicable.
126 #[derive(Debug, PartialEq, PartialOrd, Clone)]
127 pub enum MessageItem {
128     /// A D-Bus array requires all elements to be of the same type.
129     /// All elements must match the Signature.
130     Array(MessageItemArray),
131     /// A D-Bus struct allows for values of different types.
132     Struct(Vec<MessageItem>),
133     /// A D-Bus variant is a wrapper around another `MessageItem`, which
134     /// can be of any type.
135     Variant(Box<MessageItem>),
136     /// A D-Bus dictionary entry. These are only allowed inside an array.
137     DictEntry(Box<MessageItem>, Box<MessageItem>),
138     /// A D-Bus objectpath requires its content to be a valid objectpath,
139     /// so this cannot be any string.
140     ObjectPath(Path<'static>),
141     /// A D-Bus String is zero terminated, so no \0 s in the String, please.
142     /// (D-Bus strings are also - like Rust strings - required to be valid UTF-8.)
143     Str(String),
144     /// A D-Bus boolean type.
145     Bool(bool),
146     /// A D-Bus unsigned 8 bit type.
147     Byte(u8),
148     /// A D-Bus signed 16 bit type.
149     Int16(i16),
150     /// A D-Bus signed 32 bit type.
151     Int32(i32),
152     /// A D-Bus signed 64 bit type.
153     Int64(i64),
154     /// A D-Bus unsigned 16 bit type.
155     UInt16(u16),
156     /// A D-Bus unsigned 32 bit type.
157     UInt32(u32),
158     /// A D-Bus unsigned 64 bit type.
159     UInt64(u64),
160     /// A D-Bus IEEE-754 double-precision floating point type.
161     Double(f64),
162     /// D-Bus allows for sending file descriptors, which can be used to
163     /// set up SHM, unix pipes, or other communication channels.
164     UnixFd(OwnedFd),
165 }
166 
iter_get_basic<T>(i: &mut ffi::DBusMessageIter) -> T167 fn iter_get_basic<T>(i: &mut ffi::DBusMessageIter) -> T {
168     unsafe {
169         let mut c: T = mem::zeroed();
170         let p = &mut c as *mut _ as *mut c_void;
171         ffi::dbus_message_iter_get_basic(i, p);
172         c
173     }
174 }
175 
iter_append_array(i: &mut ffi::DBusMessageIter, a: &[MessageItem], t: &CStr)176 fn iter_append_array(i: &mut ffi::DBusMessageIter, a: &[MessageItem], t: &CStr) {
177     let mut subiter = new_dbus_message_iter();
178 
179     assert!(unsafe { ffi::dbus_message_iter_open_container(i, ffi::DBUS_TYPE_ARRAY, t.as_ptr(), &mut subiter) } != 0);
180     for item in a.iter() {
181 //        assert!(item.type_sig() == t);
182         item.iter_append(&mut subiter);
183     }
184     assert!(unsafe { ffi::dbus_message_iter_close_container(i, &mut subiter) } != 0);
185 }
186 
iter_append_struct(i: &mut ffi::DBusMessageIter, a: &[MessageItem])187 fn iter_append_struct(i: &mut ffi::DBusMessageIter, a: &[MessageItem]) {
188     let mut subiter = new_dbus_message_iter();
189     let res = unsafe { ffi::dbus_message_iter_open_container(i, ffi::DBUS_TYPE_STRUCT, ptr::null(), &mut subiter) };
190     assert!(res != 0);
191     for item in a.iter() {
192         item.iter_append(&mut subiter);
193     }
194     let res2 = unsafe { ffi::dbus_message_iter_close_container(i, &mut subiter) };
195     assert!(res2 != 0);
196 }
197 
iter_append_variant(i: &mut ffi::DBusMessageIter, a: &MessageItem)198 fn iter_append_variant(i: &mut ffi::DBusMessageIter, a: &MessageItem) {
199     let mut subiter = new_dbus_message_iter();
200     let asig = a.signature();
201     let atype = asig.as_cstr();
202     assert!(unsafe { ffi::dbus_message_iter_open_container(i, ffi::DBUS_TYPE_VARIANT, atype.as_ptr(), &mut subiter) } != 0);
203     a.iter_append(&mut subiter);
204     assert!(unsafe { ffi::dbus_message_iter_close_container(i, &mut subiter) } != 0);
205 }
206 
iter_append_dict(i: &mut ffi::DBusMessageIter, k: &MessageItem, v: &MessageItem)207 fn iter_append_dict(i: &mut ffi::DBusMessageIter, k: &MessageItem, v: &MessageItem) {
208     let mut subiter = new_dbus_message_iter();
209     assert!(unsafe { ffi::dbus_message_iter_open_container(i, ffi::DBUS_TYPE_DICT_ENTRY, ptr::null(), &mut subiter) } != 0);
210     k.iter_append(&mut subiter);
211     v.iter_append(&mut subiter);
212     assert!(unsafe { ffi::dbus_message_iter_close_container(i, &mut subiter) } != 0);
213 }
214 
215 impl MessageItem {
216     /// Get the D-Bus Signature for this MessageItem.
217     ///
218     /// Note: Since dictionary entries have no valid signature, calling this function for a dict entry will cause a panic.
signature(&self) -> Signature<'static>219     pub fn signature(&self) -> Signature<'static> {
220         use arg::Variant;
221         match *self {
222             MessageItem::Str(_) => <String as Arg>::signature(),
223             MessageItem::Bool(_) => <bool as Arg>::signature(),
224             MessageItem::Byte(_) => <u8 as Arg>::signature(),
225             MessageItem::Int16(_) => <i16 as Arg>::signature(),
226             MessageItem::Int32(_) => <i32 as Arg>::signature(),
227             MessageItem::Int64(_) => <i64 as Arg>::signature(),
228             MessageItem::UInt16(_) => <u16 as Arg>::signature(),
229             MessageItem::UInt32(_) => <u32 as Arg>::signature(),
230             MessageItem::UInt64(_) => <u64 as Arg>::signature(),
231             MessageItem::Double(_) => <f64 as Arg>::signature(),
232             MessageItem::Array(ref a) => a.sig.clone(),
233             MessageItem::Struct(ref s) => Signature::new(format!("({})", s.iter().fold(String::new(), |s, i| s + &*i.signature()))).unwrap(),
234             MessageItem::Variant(_) => <Variant<u8> as Arg>::signature(),
235             MessageItem::DictEntry(_, _) => { panic!("Dict entries are only valid inside arrays, and therefore has no signature on their own") },
236             MessageItem::ObjectPath(_) => <Path as Arg>::signature(),
237             MessageItem::UnixFd(_) => <OwnedFd as Arg>::signature(),
238         }
239     }
240 
241     /// Get the D-Bus ASCII type-code for this MessageItem.
242     #[deprecated(note="superseded by signature")]
243     #[allow(deprecated)]
type_sig(&self) -> super::TypeSig<'static>244     pub fn type_sig(&self) -> super::TypeSig<'static> {
245         Cow::Owned(format!("{}", self.signature()))
246     }
247 
248     /// Get the integer value for this MessageItem's type-code.
array_type(&self) -> i32249     pub fn array_type(&self) -> i32 {
250         let s = match self {
251             &MessageItem::Str(_) => ffi::DBUS_TYPE_STRING,
252             &MessageItem::Bool(_) => ffi::DBUS_TYPE_BOOLEAN,
253             &MessageItem::Byte(_) => ffi::DBUS_TYPE_BYTE,
254             &MessageItem::Int16(_) => ffi::DBUS_TYPE_INT16,
255             &MessageItem::Int32(_) => ffi::DBUS_TYPE_INT32,
256             &MessageItem::Int64(_) => ffi::DBUS_TYPE_INT64,
257             &MessageItem::UInt16(_) => ffi::DBUS_TYPE_UINT16,
258             &MessageItem::UInt32(_) => ffi::DBUS_TYPE_UINT32,
259             &MessageItem::UInt64(_) => ffi::DBUS_TYPE_UINT64,
260             &MessageItem::Double(_) => ffi::DBUS_TYPE_DOUBLE,
261             &MessageItem::Array(_) => ffi::DBUS_TYPE_ARRAY,
262             &MessageItem::Struct(_) => ffi::DBUS_TYPE_STRUCT,
263             &MessageItem::Variant(_) => ffi::DBUS_TYPE_VARIANT,
264             &MessageItem::DictEntry(_,_) => ffi::DBUS_TYPE_DICT_ENTRY,
265             &MessageItem::ObjectPath(_) => ffi::DBUS_TYPE_OBJECT_PATH,
266             &MessageItem::UnixFd(_) => ffi::DBUS_TYPE_UNIX_FD,
267         };
268         s as i32
269     }
270 
271     /// Creates a (String, Variant) dictionary from an iterator with Result passthrough (an Err will abort and return that Err)
from_dict<E, I: Iterator<Item=Result<(String, MessageItem),E>>>(i: I) -> Result<MessageItem, E>272     pub fn from_dict<E, I: Iterator<Item=Result<(String, MessageItem),E>>>(i: I) -> Result<MessageItem, E> {
273         let mut v = Vec::new();
274         for r in i {
275             let (s, vv) = try!(r);
276             v.push((s.into(), Box::new(vv).into()).into());
277         }
278         Ok(MessageItem::Array(MessageItemArray::new(v, Signature::new("a{sv}").unwrap()).unwrap()))
279     }
280 
281     /// Creates an MessageItem::Array from a list of MessageItems.
282     ///
283     /// Note: This requires `v` to be non-empty. See also
284     /// `MessageItem::from(&[T])`, which can handle empty arrays as well.
new_array(v: Vec<MessageItem>) -> Result<MessageItem,ArrayError>285     pub fn new_array(v: Vec<MessageItem>) -> Result<MessageItem,ArrayError> {
286         if v.len() == 0 {
287             return Err(ArrayError::EmptyArray);
288         }
289         let s = MessageItemArray::make_sig(&v[0]);
290         Ok(MessageItem::Array(MessageItemArray::new(v, s)?))
291     }
292 
293 
new_array2<D, I>(i: I) -> MessageItem where D: Into<MessageItem>, D: Default, I: Iterator<Item=D>294     fn new_array2<D, I>(i: I) -> MessageItem
295     where D: Into<MessageItem>, D: Default, I: Iterator<Item=D> {
296         let v: Vec<MessageItem> = i.map(|ii| ii.into()).collect();
297         let s = {
298             let d;
299             let t = if v.len() == 0 { d = D::default().into(); &d } else { &v[0] };
300             MessageItemArray::make_sig(t)
301         };
302         MessageItem::Array(MessageItemArray::new(v, s).unwrap())
303     }
304 
new_array3<'b, D: 'b, I>(i: I) -> MessageItem where D: Into<MessageItem> + Default + Clone, I: Iterator<Item=&'b D>305     fn new_array3<'b, D: 'b, I>(i: I) -> MessageItem
306     where D: Into<MessageItem> + Default + Clone, I: Iterator<Item=&'b D> {
307         MessageItem::new_array2(i.map(|ii| ii.clone()))
308     }
309 
from_iter_single(i: &mut ffi::DBusMessageIter) -> Option<MessageItem>310     fn from_iter_single(i: &mut ffi::DBusMessageIter) -> Option<MessageItem> {
311         let t = unsafe { ffi::dbus_message_iter_get_arg_type(i) };
312         match t {
313             ffi::DBUS_TYPE_INVALID => { None },
314             ffi::DBUS_TYPE_DICT_ENTRY => {
315                 let mut subiter = new_dbus_message_iter();
316                 unsafe { ffi::dbus_message_iter_recurse(i, &mut subiter) };
317                 let a = MessageItem::from_iter(&mut subiter);
318                 if a.len() != 2 { panic!("D-Bus dict entry error"); }
319                 let mut a = a.into_iter();
320                 let key = Box::new(a.next().unwrap());
321                 let value = Box::new(a.next().unwrap());
322                 Some(MessageItem::DictEntry(key, value))
323             }
324             ffi::DBUS_TYPE_VARIANT => {
325                 let mut subiter = new_dbus_message_iter();
326                 unsafe { ffi::dbus_message_iter_recurse(i, &mut subiter) };
327                 let a = MessageItem::from_iter(&mut subiter);
328                 if a.len() != 1 { panic!("D-Bus variant error"); }
329                 Some(MessageItem::Variant(Box::new(a.into_iter().next().unwrap())))
330             }
331             ffi::DBUS_TYPE_ARRAY => {
332                 let mut subiter = new_dbus_message_iter();
333                 unsafe { ffi::dbus_message_iter_recurse(i, &mut subiter) };
334                 let c = unsafe { ffi::dbus_message_iter_get_signature(&mut subiter) };
335                 let s = format!("a{}", c_str_to_slice(&(c as *const c_char)).unwrap());
336                 unsafe { ffi::dbus_free(c as *mut c_void) };
337                 let t = Signature::new(s).unwrap();
338 
339                 let a = MessageItem::from_iter(&mut subiter);
340                 Some(MessageItem::Array(MessageItemArray { v: a, sig: t }))
341             },
342             ffi::DBUS_TYPE_STRUCT => {
343                 let mut subiter = new_dbus_message_iter();
344                 unsafe { ffi::dbus_message_iter_recurse(i, &mut subiter) };
345                 Some(MessageItem::Struct(MessageItem::from_iter(&mut subiter)))
346             },
347             ffi::DBUS_TYPE_STRING => {
348                 let mut c: *const c_char = ptr::null();
349                 unsafe {
350                     let p: *mut c_void = mem::transmute(&mut c);
351                     ffi::dbus_message_iter_get_basic(i, p);
352                 };
353                 Some(MessageItem::Str(c_str_to_slice(&c).expect("D-Bus string error").to_string()))
354             },
355             ffi::DBUS_TYPE_OBJECT_PATH => {
356                 let mut c: *const c_char = ptr::null();
357                 unsafe {
358                     let p: *mut c_void = mem::transmute(&mut c);
359                     ffi::dbus_message_iter_get_basic(i, p);
360                 };
361                 let o = Path::new(c_str_to_slice(&c).expect("D-Bus object path error")).ok().expect("D-Bus object path error");
362                 Some(MessageItem::ObjectPath(o))
363             },
364             ffi::DBUS_TYPE_UNIX_FD => Some(MessageItem::UnixFd(OwnedFd::new(iter_get_basic(i)))),
365             ffi::DBUS_TYPE_BOOLEAN => Some(MessageItem::Bool(iter_get_basic::<u32>(i) != 0)),
366             ffi::DBUS_TYPE_BYTE => Some(MessageItem::Byte(iter_get_basic(i))),
367             ffi::DBUS_TYPE_INT16 => Some(MessageItem::Int16(iter_get_basic(i))),
368             ffi::DBUS_TYPE_INT32 => Some(MessageItem::Int32(iter_get_basic(i))),
369             ffi::DBUS_TYPE_INT64 => Some(MessageItem::Int64(iter_get_basic(i))),
370             ffi::DBUS_TYPE_UINT16 => Some(MessageItem::UInt16(iter_get_basic(i))),
371             ffi::DBUS_TYPE_UINT32 => Some(MessageItem::UInt32(iter_get_basic(i))),
372             ffi::DBUS_TYPE_UINT64 => Some(MessageItem::UInt64(iter_get_basic(i))),
373             ffi::DBUS_TYPE_DOUBLE => Some(MessageItem::Double(iter_get_basic(i))),
374             _ => { None /* Only the new msgarg module supports signatures */ }
375         }
376     }
377 
from_iter(i: &mut ffi::DBusMessageIter) -> Vec<MessageItem>378     fn from_iter(i: &mut ffi::DBusMessageIter) -> Vec<MessageItem> {
379         let mut v = Vec::new();
380         while let Some(m) = Self::from_iter_single(i) {
381             v.push(m);
382             unsafe { ffi::dbus_message_iter_next(i) };
383         }
384         v
385     }
386 
iter_append_basic<T>(&self, i: &mut ffi::DBusMessageIter, v: T)387     fn iter_append_basic<T>(&self, i: &mut ffi::DBusMessageIter, v: T) {
388         let t = self.array_type() as c_int;
389         let p = &v as *const _ as *const c_void;
390         unsafe {
391             ffi::dbus_message_iter_append_basic(i, t, p);
392         }
393     }
394 
iter_append(&self, i: &mut ffi::DBusMessageIter)395     fn iter_append(&self, i: &mut ffi::DBusMessageIter) {
396         match self {
397             &MessageItem::Str(ref s) => unsafe {
398                 let c = to_c_str(s);
399                 let p = mem::transmute(&c);
400                 ffi::dbus_message_iter_append_basic(i, ffi::DBUS_TYPE_STRING, p);
401             },
402             &MessageItem::Bool(b) => self.iter_append_basic(i, if b { 1u32 } else { 0u32 }),
403             &MessageItem::Byte(b) => self.iter_append_basic(i, b),
404             &MessageItem::Int16(b) => self.iter_append_basic(i, b),
405             &MessageItem::Int32(b) => self.iter_append_basic(i, b),
406             &MessageItem::Int64(b) => self.iter_append_basic(i, b),
407             &MessageItem::UInt16(b) => self.iter_append_basic(i, b),
408             &MessageItem::UInt32(b) => self.iter_append_basic(i, b),
409             &MessageItem::UInt64(b) => self.iter_append_basic(i, b),
410             &MessageItem::UnixFd(ref b) => self.iter_append_basic(i, b.as_raw_fd()),
411             &MessageItem::Double(b) => self.iter_append_basic(i, b),
412             &MessageItem::Array(ref a) => iter_append_array(i, &a.v, a.element_signature()),
413             &MessageItem::Struct(ref v) => iter_append_struct(i, &**v),
414             &MessageItem::Variant(ref b) => iter_append_variant(i, &**b),
415             &MessageItem::DictEntry(ref k, ref v) => iter_append_dict(i, &**k, &**v),
416             &MessageItem::ObjectPath(ref s) => unsafe {
417                 let c: *const libc::c_char = s.as_ref().as_ptr();
418                 let p = mem::transmute(&c);
419                 ffi::dbus_message_iter_append_basic(i, ffi::DBUS_TYPE_OBJECT_PATH, p);
420             }
421         }
422     }
423 
copy_to_iter(i: &mut ffi::DBusMessageIter, v: &[MessageItem])424     fn copy_to_iter(i: &mut ffi::DBusMessageIter, v: &[MessageItem]) {
425         for item in v.iter() {
426             item.iter_append(i);
427         }
428     }
429 
430     /// Conveniently get the inner value of a `MessageItem`
431     ///
432     /// # Example
433     /// ```
434     /// use dbus::MessageItem;
435     /// let m: MessageItem = 5i64.into();
436     /// let s: i64 = m.inner().unwrap();
437     /// assert_eq!(s, 5i64);
438     /// ```
inner<'a, T: FromMessageItem<'a>>(&'a self) -> Result<T, ()>439     pub fn inner<'a, T: FromMessageItem<'a>>(&'a self) -> Result<T, ()> {
440         T::from(self)
441     }
442 }
443 
444 
445 // For use by the msgarg module
append_messageitem(i: &mut ffi::DBusMessageIter, m: &MessageItem)446 pub fn append_messageitem(i: &mut ffi::DBusMessageIter, m: &MessageItem) {
447     m.iter_append(i)
448 }
449 
450 // For use by the msgarg module
get_messageitem(i: &mut ffi::DBusMessageIter) -> Option<MessageItem>451 pub fn get_messageitem(i: &mut ffi::DBusMessageIter) -> Option<MessageItem> {
452     MessageItem::from_iter_single(i)
453 }
454 
455 
456 macro_rules! msgitem_convert {
457     ($t: ty, $s: ident) => {
458         impl From<$t> for MessageItem { fn from(i: $t) -> MessageItem { MessageItem::$s(i) } }
459 
460         impl<'a> FromMessageItem<'a> for $t {
461             fn from(i: &'a MessageItem) -> Result<$t,()> {
462                 if let &MessageItem::$s(ref b) = i { Ok(*b) } else { Err(()) }
463             }
464         }
465     }
466 }
467 
468 msgitem_convert!(u8, Byte);
469 msgitem_convert!(u64, UInt64);
470 msgitem_convert!(u32, UInt32);
471 msgitem_convert!(u16, UInt16);
472 msgitem_convert!(i16, Int16);
473 msgitem_convert!(i32, Int32);
474 msgitem_convert!(i64, Int64);
475 msgitem_convert!(f64, Double);
476 msgitem_convert!(bool, Bool);
477 
478 
479 /// Create a `MessageItem::Array`.
480 impl<'a, T> From<&'a [T]> for MessageItem
481 where T: Into<MessageItem> + Clone + Default {
from(i: &'a [T]) -> MessageItem482     fn from(i: &'a [T]) -> MessageItem {
483         MessageItem::new_array3(i.iter())
484     }
485 }
486 
from(i: &str) -> MessageItem487 impl<'a> From<&'a str> for MessageItem { fn from(i: &str) -> MessageItem { MessageItem::Str(i.to_string()) } }
488 
from(i: String) -> MessageItem489 impl From<String> for MessageItem { fn from(i: String) -> MessageItem { MessageItem::Str(i) } }
490 
from(i: Path<'static>) -> MessageItem491 impl From<Path<'static>> for MessageItem { fn from(i: Path<'static>) -> MessageItem { MessageItem::ObjectPath(i) } }
492 
from(i: OwnedFd) -> MessageItem493 impl From<OwnedFd> for MessageItem { fn from(i: OwnedFd) -> MessageItem { MessageItem::UnixFd(i) } }
494 
495 /// Create a `MessageItem::Variant`
496 impl From<Box<MessageItem>> for MessageItem {
from(i: Box<MessageItem>) -> MessageItem497     fn from(i: Box<MessageItem>) -> MessageItem { MessageItem::Variant(i) }
498 }
499 
500 /// Create a `MessageItem::DictEntry`
501 impl From<(MessageItem, MessageItem)> for MessageItem {
from(i: (MessageItem, MessageItem)) -> MessageItem502     fn from(i: (MessageItem, MessageItem)) -> MessageItem {
503         MessageItem::DictEntry(Box::new(i.0), Box::new(i.1))
504     }
505 }
506 
507 /// Helper trait for `MessageItem::inner()`
508 pub trait FromMessageItem<'a> :Sized {
509     /// Allows converting from a MessageItem into the type it contains.
from(i: &'a MessageItem) -> Result<Self, ()>510     fn from(i: &'a MessageItem) -> Result<Self, ()>;
511 }
512 
513 impl<'a> FromMessageItem<'a> for &'a str {
from(i: &'a MessageItem) -> Result<&'a str,()>514     fn from(i: &'a MessageItem) -> Result<&'a str,()> {
515         match i {
516             &MessageItem::Str(ref b) => Ok(&b),
517             &MessageItem::ObjectPath(ref b) => Ok(&b),
518             _ => Err(()),
519         }
520     }
521 }
522 
523 impl<'a> FromMessageItem<'a> for &'a String {
from(i: &'a MessageItem) -> Result<&'a String,()>524     fn from(i: &'a MessageItem) -> Result<&'a String,()> { if let &MessageItem::Str(ref b) = i { Ok(&b) } else { Err(()) } }
525 }
526 
527 impl<'a> FromMessageItem<'a> for &'a Path<'static> {
from(i: &'a MessageItem) -> Result<&'a Path<'static>,()>528     fn from(i: &'a MessageItem) -> Result<&'a Path<'static>,()> { if let &MessageItem::ObjectPath(ref b) = i { Ok(&b) } else { Err(()) } }
529 }
530 
531 impl<'a> FromMessageItem<'a> for &'a MessageItem {
from(i: &'a MessageItem) -> Result<&'a MessageItem,()>532     fn from(i: &'a MessageItem) -> Result<&'a MessageItem,()> { if let &MessageItem::Variant(ref b) = i { Ok(&**b) } else { Err(()) } }
533 }
534 
535 impl<'a> FromMessageItem<'a> for &'a Vec<MessageItem> {
from(i: &'a MessageItem) -> Result<&'a Vec<MessageItem>,()>536     fn from(i: &'a MessageItem) -> Result<&'a Vec<MessageItem>,()> {
537         match i {
538             &MessageItem::Array(ref b) => Ok(&b.v),
539             &MessageItem::Struct(ref b) => Ok(&b),
540             _ => Err(()),
541         }
542     }
543 }
544 
545 impl<'a> FromMessageItem<'a> for &'a [MessageItem] {
from(i: &'a MessageItem) -> Result<&'a [MessageItem],()>546     fn from(i: &'a MessageItem) -> Result<&'a [MessageItem],()> { i.inner::<&Vec<MessageItem>>().map(|s| &**s) }
547 }
548 
549 impl<'a> FromMessageItem<'a> for &'a OwnedFd {
from(i: &'a MessageItem) -> Result<&'a OwnedFd,()>550     fn from(i: &'a MessageItem) -> Result<&'a OwnedFd,()> { if let &MessageItem::UnixFd(ref b) = i { Ok(b) } else { Err(()) } }
551 }
552 
553 impl<'a> FromMessageItem<'a> for (&'a MessageItem, &'a MessageItem) {
from(i: &'a MessageItem) -> Result<(&'a MessageItem, &'a MessageItem),()>554     fn from(i: &'a MessageItem) -> Result<(&'a MessageItem, &'a MessageItem),()> {
555         if let &MessageItem::DictEntry(ref k, ref v) = i { Ok((&**k, &**v)) } else { Err(()) }
556     }
557 }
558 
559 
560 /// A D-Bus message. A message contains some headers (e g sender and destination address)
561 /// and a list of MessageItems.
562 pub struct Message {
563     msg: *mut ffi::DBusMessage,
564 }
565 
566 unsafe impl Send for Message {}
567 
568 impl Message {
569     /// Creates a new method call message.
new_method_call<'d, 'p, 'i, 'm, D, P, I, M>(destination: D, path: P, iface: I, method: M) -> Result<Message, String> where D: Into<BusName<'d>>, P: Into<Path<'p>>, I: Into<Interface<'i>>, M: Into<Member<'m>>570     pub fn new_method_call<'d, 'p, 'i, 'm, D, P, I, M>(destination: D, path: P, iface: I, method: M) -> Result<Message, String>
571     where D: Into<BusName<'d>>, P: Into<Path<'p>>, I: Into<Interface<'i>>, M: Into<Member<'m>> {
572         init_dbus();
573         let (d, p, i, m) = (destination.into(), path.into(), iface.into(), method.into());
574         let ptr = unsafe {
575             ffi::dbus_message_new_method_call(d.as_ref().as_ptr(), p.as_ref().as_ptr(), i.as_ref().as_ptr(), m.as_ref().as_ptr())
576         };
577         if ptr == ptr::null_mut() { Err("D-Bus error: dbus_message_new_method_call failed".into()) }
578         else { Ok(Message { msg: ptr}) }
579     }
580 
581     /// Creates a new method call message.
method_call(destination: &BusName, path: &Path, iface: &Interface, name: &Member) -> Message582     pub fn method_call(destination: &BusName, path: &Path, iface: &Interface, name: &Member) -> Message {
583         init_dbus();
584         let ptr = unsafe {
585             ffi::dbus_message_new_method_call(destination.as_ref().as_ptr(), path.as_ref().as_ptr(),
586                 iface.as_ref().as_ptr(), name.as_ref().as_ptr())
587         };
588         if ptr == ptr::null_mut() { panic!("D-Bus error: dbus_message_new_signal failed") }
589         Message { msg: ptr}
590     }
591 
592     /// Creates a new signal message.
new_signal<P, I, M>(path: P, iface: I, name: M) -> Result<Message, String> where P: Into<Vec<u8>>, I: Into<Vec<u8>>, M: Into<Vec<u8>>593     pub fn new_signal<P, I, M>(path: P, iface: I, name: M) -> Result<Message, String>
594     where P: Into<Vec<u8>>, I: Into<Vec<u8>>, M: Into<Vec<u8>> {
595         init_dbus();
596 
597         let p = try!(Path::new(path));
598         let i = try!(Interface::new(iface));
599         let m = try!(Member::new(name));
600 
601         let ptr = unsafe {
602             ffi::dbus_message_new_signal(p.as_ref().as_ptr(), i.as_ref().as_ptr(), m.as_ref().as_ptr())
603         };
604         if ptr == ptr::null_mut() { Err("D-Bus error: dbus_message_new_signal failed".into()) }
605         else { Ok(Message { msg: ptr}) }
606     }
607 
608     /// Creates a new signal message.
signal(path: &Path, iface: &Interface, name: &Member) -> Message609     pub fn signal(path: &Path, iface: &Interface, name: &Member) -> Message {
610         init_dbus();
611         let ptr = unsafe {
612             ffi::dbus_message_new_signal(path.as_ref().as_ptr(), iface.as_ref().as_ptr(), name.as_ref().as_ptr())
613         };
614         if ptr == ptr::null_mut() { panic!("D-Bus error: dbus_message_new_signal failed") }
615         Message { msg: ptr}
616     }
617 
618     /// Creates a method reply for this method call.
new_method_return(m: &Message) -> Option<Message>619     pub fn new_method_return(m: &Message) -> Option<Message> {
620         let ptr = unsafe { ffi::dbus_message_new_method_return(m.msg) };
621         if ptr == ptr::null_mut() { None } else { Some(Message { msg: ptr} ) }
622     }
623 
624     /// Creates a method return (reply) for this method call.
method_return(&self) -> Message625     pub fn method_return(&self) -> Message {
626         let ptr = unsafe { ffi::dbus_message_new_method_return(self.msg) };
627         if ptr == ptr::null_mut() { panic!("D-Bus error: dbus_message_new_method_return failed") }
628         Message {msg: ptr}
629     }
630 
631     /// The old way to create a new error reply
new_error(m: &Message, error_name: &str, error_message: &str) -> Option<Message>632     pub fn new_error(m: &Message, error_name: &str, error_message: &str) -> Option<Message> {
633         let (en, em) = (to_c_str(error_name), to_c_str(error_message));
634         let ptr = unsafe { ffi::dbus_message_new_error(m.msg, en.as_ptr(), em.as_ptr()) };
635         if ptr == ptr::null_mut() { None } else { Some(Message { msg: ptr} ) }
636     }
637 
638     /// Creates a new error reply
error(&self, error_name: &ErrorName, error_message: &CStr) -> Message639     pub fn error(&self, error_name: &ErrorName, error_message: &CStr) -> Message {
640         let ptr = unsafe { ffi::dbus_message_new_error(self.msg, error_name.as_ref().as_ptr(), error_message.as_ptr()) };
641         if ptr == ptr::null_mut() { panic!("D-Bus error: dbus_message_new_error failed") }
642         Message { msg: ptr}
643     }
644 
645     /// Get the MessageItems that make up the message.
646     ///
647     /// Note: use `iter_init` or `get1`/`get2`/etc instead for faster access to the arguments.
648     /// This method is provided for backwards compatibility.
get_items(&self) -> Vec<MessageItem>649     pub fn get_items(&self) -> Vec<MessageItem> {
650         let mut i = new_dbus_message_iter();
651         match unsafe { ffi::dbus_message_iter_init(self.msg, &mut i) } {
652             0 => Vec::new(),
653             _ => MessageItem::from_iter(&mut i)
654         }
655     }
656 
657     /// Get the D-Bus serial of a message, if one was specified.
get_serial(&self) -> u32658     pub fn get_serial(&self) -> u32 {
659         unsafe { ffi::dbus_message_get_serial(self.msg) }
660     }
661 
662     /// Get the serial of the message this message is a reply to, if present.
get_reply_serial(&self) -> Option<u32>663     pub fn get_reply_serial(&self) -> Option<u32> {
664         let s = unsafe { ffi::dbus_message_get_reply_serial(self.msg) };
665         if s == 0 { None } else { Some(s) }
666     }
667 
668     /// Returns true if the message does not expect a reply.
get_no_reply(&self) -> bool669     pub fn get_no_reply(&self) -> bool { unsafe { ffi::dbus_message_get_no_reply(self.msg) != 0 } }
670 
671     /// Set whether or not the message expects a reply.
672     ///
673     /// Set to true if you send a method call and do not want a reply.
set_no_reply(&self, v: bool)674     pub fn set_no_reply(&self, v: bool) {
675         unsafe { ffi::dbus_message_set_no_reply(self.msg, if v { 1 } else { 0 }) }
676     }
677 
678     /// Returns true if the message can cause a service to be auto-started.
get_auto_start(&self) -> bool679     pub fn get_auto_start(&self) -> bool { unsafe { ffi::dbus_message_get_auto_start(self.msg) != 0 } }
680 
681     /// Sets whether or not the message can cause a service to be auto-started.
682     ///
683     /// Defaults to true.
set_auto_start(&self, v: bool)684     pub fn set_auto_start(&self, v: bool) {
685         unsafe { ffi::dbus_message_set_auto_start(self.msg, if v { 1 } else { 0 }) }
686     }
687 
688     /// Add one or more MessageItems to this Message.
689     ///
690     /// Note: using `append1`, `append2` or `append3` might be faster, especially for large arrays.
691     /// This method is provided for backwards compatibility.
append_items(&mut self, v: &[MessageItem])692     pub fn append_items(&mut self, v: &[MessageItem]) {
693         let mut i = new_dbus_message_iter();
694         unsafe { ffi::dbus_message_iter_init_append(self.msg, &mut i) };
695         MessageItem::copy_to_iter(&mut i, v);
696     }
697 
698     /// Appends one MessageItem to a message.
699     /// Use in builder style: e g `m.method_return().append(7i32)`
700     ///
701     /// Note: using `append1`, `append2` or `append3` might be faster, especially for large arrays.
702     /// This method is provided for backwards compatibility.
append<I: Into<MessageItem>>(self, v: I) -> Self703     pub fn append<I: Into<MessageItem>>(self, v: I) -> Self {
704         let mut i = new_dbus_message_iter();
705         unsafe { ffi::dbus_message_iter_init_append(self.msg, &mut i) };
706         MessageItem::copy_to_iter(&mut i, &[v.into()]);
707         self
708     }
709 
710     /// Appends one argument to this message.
711     /// Use in builder style: e g `m.method_return().append1(7i32)`
append1<A: Append>(mut self, a: A) -> Self712     pub fn append1<A: Append>(mut self, a: A) -> Self {
713         {
714             let mut m = IterAppend::new(&mut self);
715             m.append(a);
716         }
717         self
718     }
719 
720     /// Appends two arguments to this message.
721     /// Use in builder style: e g `m.method_return().append2(7i32, 6u8)`
append2<A1: Append, A2: Append>(mut self, a1: A1, a2: A2) -> Self722     pub fn append2<A1: Append, A2: Append>(mut self, a1: A1, a2: A2) -> Self {
723         {
724             let mut m = IterAppend::new(&mut self);
725             m.append(a1); m.append(a2);
726         }
727         self
728     }
729 
730     /// Appends three arguments to this message.
731     /// Use in builder style: e g `m.method_return().append3(7i32, 6u8, true)`
append3<A1: Append, A2: Append, A3: Append>(mut self, a1: A1, a2: A2, a3: A3) -> Self732     pub fn append3<A1: Append, A2: Append, A3: Append>(mut self, a1: A1, a2: A2, a3: A3) -> Self {
733         {
734             let mut m = IterAppend::new(&mut self);
735             m.append(a1); m.append(a2); m.append(a3);
736         }
737         self
738     }
739 
740     /// Appends RefArgs to this message.
741     /// Use in builder style: e g `m.method_return().append_ref(&[7i32, 6u8, true])`
append_ref<A: RefArg>(mut self, r: &[A]) -> Self742     pub fn append_ref<A: RefArg>(mut self, r: &[A]) -> Self {
743         {
744             let mut m = IterAppend::new(&mut self);
745             for rr in r {
746                 rr.append(&mut m);
747             }
748         }
749         self
750     }
751 
752     /// Gets the first argument from the message, if that argument is of type G1.
753     /// Returns None if there are not enough arguments, or if types don't match.
get1<'a, G1: Get<'a>>(&'a self) -> Option<G1>754     pub fn get1<'a, G1: Get<'a>>(&'a self) -> Option<G1> {
755         let mut i = Iter::new(&self);
756         i.get()
757     }
758 
759     /// Gets the first two arguments from the message, if those arguments are of type G1 and G2.
760     /// Returns None if there are not enough arguments, or if types don't match.
get2<'a, G1: Get<'a>, G2: Get<'a>>(&'a self) -> (Option<G1>, Option<G2>)761     pub fn get2<'a, G1: Get<'a>, G2: Get<'a>>(&'a self) -> (Option<G1>, Option<G2>) {
762         let mut i = Iter::new(&self);
763         let g1 = i.get();
764         if !i.next() { return (g1, None); }
765         (g1, i.get())
766     }
767 
768     /// Gets the first three arguments from the message, if those arguments are of type G1, G2 and G3.
769     /// Returns None if there are not enough arguments, or if types don't match.
get3<'a, G1: Get<'a>, G2: Get<'a>, G3: Get<'a>>(&'a self) -> (Option<G1>, Option<G2>, Option<G3>)770     pub fn get3<'a, G1: Get<'a>, G2: Get<'a>, G3: Get<'a>>(&'a self) -> (Option<G1>, Option<G2>, Option<G3>) {
771         let mut i = Iter::new(&self);
772         let g1 = i.get();
773         if !i.next() { return (g1, None, None) }
774         let g2 = i.get();
775         if !i.next() { return (g1, g2, None) }
776         (g1, g2, i.get())
777     }
778 
779     /// Gets the first four arguments from the message, if those arguments are of type G1, G2, G3 and G4.
780     /// Returns None if there are not enough arguments, or if types don't match.
get4<'a, G1: Get<'a>, G2: Get<'a>, G3: Get<'a>, G4: Get<'a>>(&'a self) -> (Option<G1>, Option<G2>, Option<G3>, Option<G4>)781     pub fn get4<'a, G1: Get<'a>, G2: Get<'a>, G3: Get<'a>, G4: Get<'a>>(&'a self) -> (Option<G1>, Option<G2>, Option<G3>, Option<G4>) {
782         let mut i = Iter::new(&self);
783         let g1 = i.get();
784         if !i.next() { return (g1, None, None, None) }
785         let g2 = i.get();
786         if !i.next() { return (g1, g2, None, None) }
787         let g3 = i.get();
788         if !i.next() { return (g1, g2, g3, None) }
789         (g1, g2, g3, i.get())
790     }
791 
792     /// Gets the first five arguments from the message, if those arguments are of type G1, G2, G3 and G4.
793     /// Returns None if there are not enough arguments, or if types don't match.
794     /// Note: If you need more than five arguments, use `iter_init` instead.
get5<'a, G1: Get<'a>, G2: Get<'a>, G3: Get<'a>, G4: Get<'a>, G5: Get<'a>>(&'a self) -> (Option<G1>, Option<G2>, Option<G3>, Option<G4>, Option<G5>)795     pub fn get5<'a, G1: Get<'a>, G2: Get<'a>, G3: Get<'a>, G4: Get<'a>, G5: Get<'a>>(&'a self) -> (Option<G1>, Option<G2>, Option<G3>, Option<G4>, Option<G5>) {
796         let mut i = Iter::new(&self);
797         let g1 = i.get();
798         if !i.next() { return (g1, None, None, None, None) }
799         let g2 = i.get();
800         if !i.next() { return (g1, g2, None, None, None) }
801         let g3 = i.get();
802         if !i.next() { return (g1, g2, g3, None, None) }
803         let g4 = i.get();
804         if !i.next() { return (g1, g2, g3, g4, None) }
805         (g1, g2, g3, g4, i.get())
806     }
807 
808     /// Gets the first argument from the message, if that argument is of type G1.
809     ///
810     /// Returns a TypeMismatchError if there are not enough arguments, or if types don't match.
read1<'a, G1: Arg + Get<'a>>(&'a self) -> Result<G1, TypeMismatchError>811     pub fn read1<'a, G1: Arg + Get<'a>>(&'a self) -> Result<G1, TypeMismatchError> {
812         let mut i = Iter::new(&self);
813         i.read()
814     }
815 
816     /// Gets the first two arguments from the message, if those arguments are of type G1 and G2.
817     ///
818     /// Returns a TypeMismatchError if there are not enough arguments, or if types don't match.
read2<'a, G1: Arg + Get<'a>, G2: Arg + Get<'a>>(&'a self) -> Result<(G1, G2), TypeMismatchError>819     pub fn read2<'a, G1: Arg + Get<'a>, G2: Arg + Get<'a>>(&'a self) -> Result<(G1, G2), TypeMismatchError> {
820         let mut i = Iter::new(&self);
821         Ok((try!(i.read()), try!(i.read())))
822     }
823 
824     /// Gets the first three arguments from the message, if those arguments are of type G1, G2 and G3.
825     ///
826     /// Returns a TypeMismatchError if there are not enough arguments, or if types don't match.
read3<'a, G1: Arg + Get<'a>, G2: Arg + Get<'a>, G3: Arg + Get<'a>>(&'a self) -> Result<(G1, G2, G3), TypeMismatchError>827     pub fn read3<'a, G1: Arg + Get<'a>, G2: Arg + Get<'a>, G3: Arg + Get<'a>>(&'a self) ->
828         Result<(G1, G2, G3), TypeMismatchError> {
829         let mut i = Iter::new(&self);
830         Ok((try!(i.read()), try!(i.read()), try!(i.read())))
831     }
832 
833     /// Gets the first four arguments from the message, if those arguments are of type G1, G2, G3 and G4.
834     ///
835     /// Returns a TypeMismatchError if there are not enough arguments, or if types don't match.
read4<'a, G1: Arg + Get<'a>, G2: Arg + Get<'a>, G3: Arg + Get<'a>, G4: Arg + Get<'a>>(&'a self) -> Result<(G1, G2, G3, G4), TypeMismatchError>836     pub fn read4<'a, G1: Arg + Get<'a>, G2: Arg + Get<'a>, G3: Arg + Get<'a>, G4: Arg + Get<'a>>(&'a self) ->
837         Result<(G1, G2, G3, G4), TypeMismatchError> {
838         let mut i = Iter::new(&self);
839         Ok((try!(i.read()), try!(i.read()), try!(i.read()), try!(i.read())))
840     }
841 
842     /// Gets the first five arguments from the message, if those arguments are of type G1, G2, G3, G4 and G5.
843     ///
844     /// Returns a TypeMismatchError if there are not enough arguments, or if types don't match.
845     /// Note: If you need more than five arguments, use `iter_init` instead.
read5<'a, G1: Arg + Get<'a>, G2: Arg + Get<'a>, G3: Arg + Get<'a>, G4: Arg + Get<'a>, G5: Arg + Get<'a>>(&'a self) -> Result<(G1, G2, G3, G4, G5), TypeMismatchError>846     pub fn read5<'a, G1: Arg + Get<'a>, G2: Arg + Get<'a>, G3: Arg + Get<'a>, G4: Arg + Get<'a>, G5: Arg + Get<'a>>(&'a self) ->
847         Result<(G1, G2, G3, G4, G5), TypeMismatchError> {
848         let mut i = Iter::new(&self);
849         Ok((try!(i.read()), try!(i.read()), try!(i.read()), try!(i.read()), try!(i.read())))
850     }
851 
852     /// Returns a struct for retreiving the arguments from a message. Supersedes get_items().
iter_init<'a>(&'a self) -> Iter<'a>853     pub fn iter_init<'a>(&'a self) -> Iter<'a> { Iter::new(&self) }
854 
855     /// Gets the MessageType of the Message.
msg_type(&self) -> MessageType856     pub fn msg_type(&self) -> MessageType {
857         unsafe { mem::transmute(ffi::dbus_message_get_type(self.msg)) }
858     }
859 
msg_internal_str<'a>(&'a self, c: *const libc::c_char) -> Option<&'a [u8]>860     fn msg_internal_str<'a>(&'a self, c: *const libc::c_char) -> Option<&'a [u8]> {
861         if c == ptr::null() { None }
862         else { Some( unsafe { CStr::from_ptr(c) }.to_bytes_with_nul()) }
863     }
864 
865     /// Gets the name of the connection that originated this message.
sender<'a>(&'a self) -> Option<BusName<'a>>866     pub fn sender<'a>(&'a self) -> Option<BusName<'a>> {
867         self.msg_internal_str(unsafe { ffi::dbus_message_get_sender(self.msg) })
868             .map(|s| unsafe { BusName::from_slice_unchecked(s) })
869     }
870 
871     /// Returns a tuple of (Message type, Path, Interface, Member) of the current message.
headers(&self) -> (MessageType, Option<String>, Option<String>, Option<String>)872     pub fn headers(&self) -> (MessageType, Option<String>, Option<String>, Option<String>) {
873         let p = unsafe { ffi::dbus_message_get_path(self.msg) };
874         let i = unsafe { ffi::dbus_message_get_interface(self.msg) };
875         let m = unsafe { ffi::dbus_message_get_member(self.msg) };
876         (self.msg_type(),
877          c_str_to_slice(&p).map(|s| s.to_string()),
878          c_str_to_slice(&i).map(|s| s.to_string()),
879          c_str_to_slice(&m).map(|s| s.to_string()))
880     }
881 
882     /// Gets the object path this Message is being sent to.
path<'a>(&'a self) -> Option<Path<'a>>883     pub fn path<'a>(&'a self) -> Option<Path<'a>> {
884         self.msg_internal_str(unsafe { ffi::dbus_message_get_path(self.msg) })
885             .map(|s| unsafe { Path::from_slice_unchecked(s) })
886     }
887 
888     /// Gets the destination this Message is being sent to.
destination<'a>(&'a self) -> Option<BusName<'a>>889     pub fn destination<'a>(&'a self) -> Option<BusName<'a>> {
890         self.msg_internal_str(unsafe { ffi::dbus_message_get_destination(self.msg) })
891             .map(|s| unsafe { BusName::from_slice_unchecked(s) })
892     }
893 
894     /// Sets the destination of this Message
895     ///
896     /// If dest is none, that means broadcast to all relevant destinations.
set_destination(&mut self, dest: Option<BusName>)897     pub fn set_destination(&mut self, dest: Option<BusName>) {
898         let c_dest = dest.as_ref().map(|d| d.as_cstr().as_ptr()).unwrap_or(ptr::null());
899         assert!(unsafe { ffi::dbus_message_set_destination(self.msg, c_dest) } != 0);
900     }
901 
902     /// Gets the interface this Message is being sent to.
interface<'a>(&'a self) -> Option<Interface<'a>>903     pub fn interface<'a>(&'a self) -> Option<Interface<'a>> {
904         self.msg_internal_str(unsafe { ffi::dbus_message_get_interface(self.msg) })
905             .map(|s| unsafe { Interface::from_slice_unchecked(s) })
906     }
907 
908     /// Gets the interface member being called.
member<'a>(&'a self) -> Option<Member<'a>>909     pub fn member<'a>(&'a self) -> Option<Member<'a>> {
910         self.msg_internal_str(unsafe { ffi::dbus_message_get_member(self.msg) })
911             .map(|s| unsafe { Member::from_slice_unchecked(s) })
912     }
913 
914     /// When the remote end returns an error, the message itself is
915     /// correct but its contents is an error. This method will
916     /// transform such an error to a D-Bus Error or otherwise return
917     /// the original message.
as_result(&mut self) -> Result<&mut Message, Error>918     pub fn as_result(&mut self) -> Result<&mut Message, Error> {
919         self.set_error_from_msg().map(|_| self)
920     }
921 
set_error_from_msg(&self) -> Result<(), Error>922     pub (super) fn set_error_from_msg(&self) -> Result<(), Error> {
923         let mut e = Error::empty();
924         if unsafe { ffi::dbus_set_error_from_message(e.get_mut(), self.msg) } != 0 { Err(e) }
925         else { Ok(()) }
926     }
927 
ptr(&self) -> *mut ffi::DBusMessage928     pub (crate) fn ptr(&self) -> *mut ffi::DBusMessage { self.msg }
929 
from_ptr(ptr: *mut ffi::DBusMessage, add_ref: bool) -> Message930     pub (crate) fn from_ptr(ptr: *mut ffi::DBusMessage, add_ref: bool) -> Message {
931         if add_ref {
932             unsafe { ffi::dbus_message_ref(ptr) };
933         }
934         Message { msg: ptr }
935     }
936 
937 }
938 
939 impl Drop for Message {
drop(&mut self)940     fn drop(&mut self) {
941         unsafe {
942             ffi::dbus_message_unref(self.msg);
943         }
944     }
945 }
946 
947 impl fmt::Debug for Message {
fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error>948     fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> {
949         write!(f, "{:?}", self.headers())
950     }
951 }
952 
953 /// A convenience struct that wraps connection, destination and path.
954 ///
955 /// Useful if you want to make many method calls to the same destination path.
956 #[derive(Clone, Debug)]
957 pub struct ConnPath<'a, C> {
958     /// Some way to access the connection, e g a &Connection or Rc<Connection>
959     pub conn: C,
960     /// Destination, i e what D-Bus service you're communicating with
961     pub dest: BusName<'a>,
962     /// Object path on the destination
963     pub path: Path<'a>,
964     /// Timeout in milliseconds for blocking method calls
965     pub timeout: i32,
966 }
967 
968 impl<'a, C: ::std::ops::Deref<Target=Connection>> ConnPath<'a, C> {
969     /// Make a D-Bus method call, where you can append arguments inside the closure.
method_call_with_args<F: FnOnce(&mut Message)>(&self, i: &Interface, m: &Member, f: F) -> Result<Message, Error>970     pub fn method_call_with_args<F: FnOnce(&mut Message)>(&self, i: &Interface, m: &Member, f: F) -> Result<Message, Error> {
971         let mut msg = Message::method_call(&self.dest, &self.path, i, m);
972         f(&mut msg);
973         self.conn.send_with_reply_and_block(msg, self.timeout)
974     }
975 
976     /// Emit a D-Bus signal, where you can append arguments inside the closure.
signal_with_args<F: FnOnce(&mut Message)>(&self, i: &Interface, m: &Member, f: F) -> Result<u32, Error>977     pub fn signal_with_args<F: FnOnce(&mut Message)>(&self, i: &Interface, m: &Member, f: F) -> Result<u32, Error> {
978         let mut msg = Message::signal(&self.path, i, m);
979         f(&mut msg);
980         self.conn.send(msg).map_err(|_| Error::new_custom("org.freedesktop.DBus.Error.Failed", "Sending signal failed"))
981     }
982 
983     /// Emit a D-Bus signal, where the arguments are in a struct.
emit<S: SignalArgs>(&self, signal: &S) -> Result<u32, Error>984     pub fn emit<S: SignalArgs>(&self, signal: &S) -> Result<u32, Error> {
985         let msg = signal.to_emit_message(&self.path);
986         self.conn.send(msg).map_err(|_| Error::new_custom("org.freedesktop.DBus.Error.Failed", "Sending signal failed"))
987     }
988 }
989 
990 // For purpose of testing the library only.
991 #[cfg(test)]
message_set_serial(m: &mut Message, s: u32)992 pub (crate) fn message_set_serial(m: &mut Message, s: u32) {
993     unsafe { ffi::dbus_message_set_serial(m.msg, s) };
994 }
995 
996 #[cfg(test)]
997 mod test {
998     extern crate tempdir;
999 
1000     use super::super::{Connection, Message, MessageType, BusType, MessageItem, OwnedFd, libc, Path, BusName};
1001 
1002     #[test]
unix_fd()1003     fn unix_fd() {
1004         use std::io::prelude::*;
1005         use std::io::SeekFrom;
1006         use std::fs::OpenOptions;
1007         use std::os::unix::io::AsRawFd;
1008 
1009         let c = Connection::get_private(BusType::Session).unwrap();
1010         c.register_object_path("/hello").unwrap();
1011         let mut m = Message::new_method_call(&c.unique_name(), "/hello", "com.example.hello", "Hello").unwrap();
1012         let tempdir = tempdir::TempDir::new("dbus-rs-test").unwrap();
1013         let mut filename = tempdir.path().to_path_buf();
1014         filename.push("test");
1015         println!("Creating file {:?}", filename);
1016         let mut file = OpenOptions::new().create(true).read(true).write(true).open(&filename).unwrap();
1017         file.write_all(b"z").unwrap();
1018         file.seek(SeekFrom::Start(0)).unwrap();
1019         let ofd = OwnedFd::new(file.as_raw_fd());
1020         m.append_items(&[MessageItem::UnixFd(ofd.clone())]);
1021         println!("Sending {:?}", m.get_items());
1022         c.send(m).unwrap();
1023 
1024         loop { for n in c.incoming(1000) {
1025             if n.msg_type() == MessageType::MethodCall {
1026                 let z: OwnedFd = n.read1().unwrap();
1027                 println!("Got {:?}", z);
1028                 let mut q: libc::c_char = 100;
1029                 assert_eq!(1, unsafe { libc::read(z.as_raw_fd(), &mut q as *mut _ as *mut libc::c_void, 1) });
1030                 assert_eq!(q, 'z' as libc::c_char);
1031                 return;
1032             } else {
1033                 println!("Got {:?}", n);
1034             }
1035         }}
1036     }
1037 
1038     #[test]
message_types()1039     fn message_types() {
1040         let c = Connection::get_private(BusType::Session).unwrap();
1041         c.register_object_path("/hello").unwrap();
1042         let mut m = Message::new_method_call(&c.unique_name(), "/hello", "com.example.hello", "Hello").unwrap();
1043         m.append_items(&[
1044             2000u16.into(),
1045             MessageItem::new_array(vec!(129u8.into())).unwrap(),
1046             ["Hello", "world"][..].into(),
1047             987654321u64.into(),
1048             (-1i32).into(),
1049             format!("Hello world").into(),
1050             (-3.14f64).into(),
1051             MessageItem::Struct(vec!(256i16.into())),
1052             Path::new("/some/path").unwrap().into(),
1053             MessageItem::new_array(vec!((123543u32.into(), true.into()).into())).unwrap()
1054         ]);
1055         let sending = format!("{:?}", m.get_items());
1056         println!("Sending {}", sending);
1057         c.send(m).unwrap();
1058 
1059         loop { for n in c.incoming(1000) {
1060             if n.msg_type() == MessageType::MethodCall {
1061                 let receiving = format!("{:?}", n.get_items());
1062                 println!("Receiving {}", receiving);
1063                 assert_eq!(sending, receiving);
1064                 return;
1065             } else {
1066                 println!("Got {:?}", n);
1067             }
1068         }}
1069     }
1070 
1071     #[test]
dict_of_dicts()1072     fn dict_of_dicts() {
1073         use std::collections::BTreeMap;
1074 
1075         let officeactions: BTreeMap<&'static str, MessageItem> = BTreeMap::new();
1076         let mut officethings = BTreeMap::new();
1077         officethings.insert("pencil", 2u16.into());
1078         officethings.insert("paper", 5u16.into());
1079         let mut homethings = BTreeMap::new();
1080         homethings.insert("apple", 11u16.into());
1081         let mut homeifaces = BTreeMap::new();
1082         homeifaces.insert("getThings", homethings);
1083         let mut officeifaces = BTreeMap::new();
1084         officeifaces.insert("getThings", officethings);
1085         officeifaces.insert("getActions", officeactions);
1086         let mut paths = BTreeMap::new();
1087         paths.insert("/hello/office", officeifaces);
1088         paths.insert("/hello/home", homeifaces);
1089 
1090         println!("Original treemap: {:?}", paths);
1091         let m = MessageItem::new_array(paths.iter().map(
1092             |(path, ifaces)| (MessageItem::ObjectPath(Path::new(*path).unwrap()),
1093                 MessageItem::new_array(ifaces.iter().map(
1094                     |(iface, props)| (iface.to_string().into(),
1095                         MessageItem::from_dict::<(),_>(props.iter().map(
1096                             |(name, value)| Ok((name.to_string(), value.clone()))
1097                         )).unwrap()
1098                     ).into()
1099                 ).collect()).unwrap()
1100             ).into()
1101         ).collect()).unwrap();
1102         println!("As MessageItem: {:?}", m);
1103         assert_eq!(&*m.signature(), "a{oa{sa{sv}}}");
1104 
1105         let c = Connection::get_private(BusType::Session).unwrap();
1106         c.register_object_path("/hello").unwrap();
1107         let mut msg = Message::new_method_call(&c.unique_name(), "/hello", "org.freedesktop.DBusObjectManager", "GetManagedObjects").unwrap();
1108         msg.append_items(&[m]);
1109         let sending = format!("{:?}", msg.get_items());
1110         println!("Sending {}", sending);
1111         c.send(msg).unwrap();
1112 
1113         loop { for n in c.incoming(1000) {
1114             if n.msg_type() == MessageType::MethodCall {
1115                 let receiving = format!("{:?}", n.get_items());
1116                 println!("Receiving {}", receiving);
1117                 assert_eq!(sending, receiving);
1118                 return;
1119             } else {
1120                 println!("Got {:?}", n);
1121             }
1122         } }
1123     }
1124 
1125     #[test]
issue24()1126     fn issue24() {
1127         let c = Connection::get_private(BusType::Session).unwrap();
1128         let mut m = Message::new_method_call("org.test.rust", "/", "org.test.rust", "Test").unwrap();
1129 
1130         let a = MessageItem::from("test".to_string());
1131         let b = MessageItem::from("test".to_string());
1132         let foo = MessageItem::Struct(vec!(a, b));
1133         let bar = foo.clone();
1134 
1135         let args = [MessageItem::new_array(vec!(foo, bar)).unwrap()];
1136         println!("{:?}", args);
1137 
1138         m.append_items(&args);
1139         c.send(m).unwrap();
1140     }
1141 
1142     #[test]
set_valid_destination()1143     fn set_valid_destination() {
1144         let mut m = Message::new_method_call("org.test.rust", "/", "org.test.rust", "Test").unwrap();
1145         let d = Some(BusName::new(":1.14").unwrap());
1146         m.set_destination(d);
1147 
1148         assert!(!m.get_no_reply());
1149         m.set_no_reply(true);
1150         assert!(m.get_no_reply());
1151     }
1152 }
1153