1 use super::*;
2 use {Signature, Path, Message, ffi, OwnedFd};
3 use std::marker::PhantomData;
4 use std::{ptr, mem, any, fmt};
5 use super::check;
6 use std::ffi::{CString};
7 use std::os::raw::{c_void, c_int};
8 use std::collections::HashMap;
9 use std::hash::Hash;
10 
11 // Map DBus-Type -> Alignment. Copied from _dbus_marshal_write_fixed_multi in
12 // http://dbus.freedesktop.org/doc/api/html/dbus-marshal-basic_8c_source.html#l01020
13 // Note that Rust booleans are one byte, dbus booleans are four bytes!
14 const FIXED_ARRAY_ALIGNMENTS: [(ArgType, usize); 9] = [
15     (ArgType::Byte, 1),
16     (ArgType::Int16, 2),
17     (ArgType::UInt16, 2),
18     (ArgType::UInt32, 4),
19     (ArgType::Int32, 4),
20     (ArgType::Boolean, 4),
21     (ArgType::Int64, 8),
22     (ArgType::UInt64, 8),
23     (ArgType::Double, 8)
24 ];
25 
26 /// Represents a D-Bus array.
27 impl<'a, T: Arg> Arg for &'a [T] {
28     const ARG_TYPE: ArgType = ArgType::Array;
signature() -> Signature<'static>29     fn signature() -> Signature<'static> { Signature::from(format!("a{}", T::signature())) }
30 }
31 
array_append<T: Arg, F: FnMut(&T, &mut IterAppend)>(z: &[T], i: &mut IterAppend, mut f: F)32 fn array_append<T: Arg, F: FnMut(&T, &mut IterAppend)>(z: &[T], i: &mut IterAppend, mut f: F) {
33     let zptr = z.as_ptr();
34     let zlen = z.len() as i32;
35 
36     // Can we do append_fixed_array?
37     let a = (T::ARG_TYPE, mem::size_of::<T>());
38     let can_fixed_array = (zlen > 1) && (z.len() == zlen as usize) && FIXED_ARRAY_ALIGNMENTS.iter().any(|&v| v == a);
39 
40     i.append_container(ArgType::Array, Some(T::signature().as_cstr()), |s|
41         if can_fixed_array { unsafe { check("dbus_message_iter_append_fixed_array",
42             ffi::dbus_message_iter_append_fixed_array(&mut s.0, a.0 as c_int, &zptr as *const _ as *const c_void, zlen)) }}
43         else { for arg in z { f(arg, s); }}
44     );
45 }
46 
47 /// Appends a D-Bus array. Note: In case you have a large array of a type that implements FixedArray,
48 /// using this method will be more efficient than using an Array.
49 impl<'a, T: Arg + Append + Clone> Append for &'a [T] {
append(self, i: &mut IterAppend)50     fn append(self, i: &mut IterAppend) {
51         array_append(self, i, |arg, s| arg.clone().append(s));
52     }
53 }
54 
55 impl<'a, T: Arg + RefArg> RefArg for &'a [T] {
arg_type(&self) -> ArgType56     fn arg_type(&self) -> ArgType { ArgType::Array }
signature(&self) -> Signature<'static>57     fn signature(&self) -> Signature<'static> { Signature::from(format!("a{}", <T as Arg>::signature())) }
append(&self, i: &mut IterAppend)58     fn append(&self, i: &mut IterAppend) {
59         array_append(self, i, |arg, s| (arg as &RefArg).append(s));
60     }
61     #[inline]
as_any(&self) -> &any::Any where Self: 'static62     fn as_any(&self) -> &any::Any where Self: 'static { self }
63     #[inline]
as_any_mut(&mut self) -> &mut any::Any where Self: 'static64     fn as_any_mut(&mut self) -> &mut any::Any where Self: 'static { self }
65 
box_clone(&self) -> Box<RefArg + 'static>66     fn box_clone(&self) -> Box<RefArg + 'static> {
67         Box::new(InternalArray {
68             inner_sig: <T as Arg>::signature(),
69             data: self.iter().map(|x| x.box_clone()).collect(),
70         })
71     }
72 }
73 
74 impl<T: Arg + RefArg> RefArg for Vec<T> {
arg_type(&self) -> ArgType75     fn arg_type(&self) -> ArgType { ArgType::Array }
signature(&self) -> Signature<'static>76     fn signature(&self) -> Signature<'static> { Signature::from(format!("a{}", <T as Arg>::signature())) }
append(&self, i: &mut IterAppend)77     fn append(&self, i: &mut IterAppend) {
78         array_append(&self, i, |arg, s| (arg as &RefArg).append(s));
79     }
80     #[inline]
as_any(&self) -> &any::Any where Self: 'static81     fn as_any(&self) -> &any::Any where Self: 'static { self }
82     #[inline]
as_any_mut(&mut self) -> &mut any::Any where Self: 'static83     fn as_any_mut(&mut self) -> &mut any::Any where Self: 'static { self }
as_iter<'a>(&'a self) -> Option<Box<Iterator<Item=&'a RefArg> + 'a>>84     fn as_iter<'a>(&'a self) -> Option<Box<Iterator<Item=&'a RefArg> + 'a>> {
85         Some(Box::new(self.iter().map(|b| b as &RefArg)))
86     }
87     #[inline]
box_clone(&self) -> Box<RefArg + 'static>88     fn box_clone(&self) -> Box<RefArg + 'static> { (&**self).box_clone() }
89 }
90 
91 
92 impl<'a, T: FixedArray> Get<'a> for &'a [T] {
get(i: &mut Iter<'a>) -> Option<&'a [T]>93     fn get(i: &mut Iter<'a>) -> Option<&'a [T]> {
94         debug_assert!(FIXED_ARRAY_ALIGNMENTS.iter().any(|&v| v == (T::ARG_TYPE, mem::size_of::<T>())));
95         i.recurse(Self::ARG_TYPE).and_then(|mut si| unsafe {
96             let etype = ffi::dbus_message_iter_get_element_type(&mut i.0);
97 
98             if etype != T::ARG_TYPE as c_int { return None };
99 
100             let mut v = ptr::null_mut();
101             let mut i = 0;
102             ffi::dbus_message_iter_get_fixed_array(&mut si.0, &mut v as *mut _ as *mut c_void, &mut i);
103             if v == ptr::null_mut() {
104                 assert_eq!(i, 0);
105                 Some(&[][..])
106             } else {
107                 Some(::std::slice::from_raw_parts(v, i as usize))
108             }
109         })
110     }
111 }
112 
113 
114 #[derive(Copy, Clone, Debug)]
115 /// Append a D-Bus dict type (i e, an array of dict entries).
116 ///
117 /// See the argument guide and module level documentation for details and alternatives.
118 pub struct Dict<'a, K: DictKey, V: Arg, I>(I, PhantomData<(&'a Message, *const K, *const V)>);
119 
120 impl<'a, K: DictKey, V: Arg, I> Dict<'a, K, V, I> {
entry_sig() -> String121     fn entry_sig() -> String { format!("{{{}{}}}", K::signature(), V::signature()) }
122 }
123 
124 impl<'a, K: 'a + DictKey, V: 'a + Append + Arg, I: Iterator<Item=(K, V)>> Dict<'a, K, V, I> {
125     /// Creates a new Dict from an iterator. The iterator is consumed when appended.
new<J: IntoIterator<IntoIter=I, Item=(K, V)>>(j: J) -> Dict<'a, K, V, I>126     pub fn new<J: IntoIterator<IntoIter=I, Item=(K, V)>>(j: J) -> Dict<'a, K, V, I> { Dict(j.into_iter(), PhantomData) }
127 }
128 
129 impl<'a, K: DictKey, V: Arg, I> Arg for Dict<'a, K, V, I> {
130     const ARG_TYPE: ArgType = ArgType::Array;
signature() -> Signature<'static>131     fn signature() -> Signature<'static> {
132         Signature::from(format!("a{}", Self::entry_sig())) }
133 }
134 
135 impl<'a, K: 'a + DictKey + Append, V: 'a + Append + Arg, I: Iterator<Item=(K, V)>> Append for Dict<'a, K, V, I> {
append(self, i: &mut IterAppend)136     fn append(self, i: &mut IterAppend) {
137         let z = self.0;
138         i.append_container(Self::ARG_TYPE, Some(&CString::new(Self::entry_sig()).unwrap()), |s| for (k, v) in z {
139             s.append_container(ArgType::DictEntry, None, |ss| {
140                 k.append(ss);
141                 v.append(ss);
142             })
143         });
144     }
145 }
146 
147 
148 impl<'a, K: DictKey + Get<'a>, V: Arg + Get<'a>> Get<'a> for Dict<'a, K, V, Iter<'a>> {
get(i: &mut Iter<'a>) -> Option<Self>149     fn get(i: &mut Iter<'a>) -> Option<Self> {
150         i.recurse(Self::ARG_TYPE).map(|si| Dict(si, PhantomData))
151         // TODO: Verify full element signature?
152     }
153 }
154 
155 impl<'a, K: DictKey + Get<'a>, V: Arg + Get<'a>> Iterator for Dict<'a, K, V, Iter<'a>> {
156     type Item = (K, V);
next(&mut self) -> Option<(K, V)>157     fn next(&mut self) -> Option<(K, V)> {
158         let i = self.0.recurse(ArgType::DictEntry).and_then(|mut si| {
159             let k = si.get();
160             if k.is_none() { return None };
161             assert!(si.next());
162             let v = si.get();
163             if v.is_none() { return None };
164             Some((k.unwrap(), v.unwrap()))
165         });
166         self.0.next();
167         i
168     }
169 }
170 
171 impl<K: DictKey, V: Arg> Arg for HashMap<K, V> {
172     const ARG_TYPE: ArgType = ArgType::Array;
signature() -> Signature<'static>173     fn signature() -> Signature<'static> {
174         Signature::from(format!("a{{{}{}}}", K::signature(), V::signature())) }
175 }
176 
177 impl<K: DictKey + Append + Eq + Hash, V: Arg + Append> Append for HashMap<K, V> {
append(self, i: &mut IterAppend)178     fn append(self, i: &mut IterAppend) {
179         Dict::new(self.into_iter()).append(i);
180     }
181 }
182 
183 impl<'a, K: DictKey + Get<'a> + Eq + Hash, V: Arg + Get<'a>> Get<'a> for HashMap<K, V> {
get(i: &mut Iter<'a>) -> Option<Self>184     fn get(i: &mut Iter<'a>) -> Option<Self> {
185         // TODO: Full element signature is not verified.
186         Dict::get(i).map(|d| d.into_iter().collect())
187     }
188 }
189 
190 impl<K: DictKey + RefArg + Eq + Hash, V: RefArg + Arg> RefArg for HashMap<K, V> {
arg_type(&self) -> ArgType191     fn arg_type(&self) -> ArgType { ArgType::Array }
signature(&self) -> Signature<'static>192     fn signature(&self) -> Signature<'static> { format!("a{{{}{}}}", <K as Arg>::signature(), <V as Arg>::signature()).into() }
append(&self, i: &mut IterAppend)193     fn append(&self, i: &mut IterAppend) {
194         let sig = CString::new(format!("{{{}{}}}", <K as Arg>::signature(), <V as Arg>::signature())).unwrap();
195         i.append_container(ArgType::Array, Some(&sig), |s| for (k, v) in self {
196             s.append_container(ArgType::DictEntry, None, |ss| {
197                 k.append(ss);
198                 v.append(ss);
199             })
200         });
201     }
202     #[inline]
as_any(&self) -> &any::Any where Self: 'static203     fn as_any(&self) -> &any::Any where Self: 'static { self }
204     #[inline]
as_any_mut(&mut self) -> &mut any::Any where Self: 'static205     fn as_any_mut(&mut self) -> &mut any::Any where Self: 'static { self }
as_iter<'b>(&'b self) -> Option<Box<Iterator<Item=&'b RefArg> + 'b>>206     fn as_iter<'b>(&'b self) -> Option<Box<Iterator<Item=&'b RefArg> + 'b>> {
207         Some(Box::new(self.iter().flat_map(|(k, v)| vec![k as &RefArg, v as &RefArg].into_iter())))
208     }
209     #[inline]
box_clone(&self) -> Box<RefArg + 'static>210     fn box_clone(&self) -> Box<RefArg + 'static> {
211         Box::new(InternalDict {
212             outer_sig: self.signature(),
213             data: self.iter().map(|(k, v)| (k.box_clone(), v.box_clone())).collect(),
214         })
215     }
216 }
217 
218 impl<T: Arg> Arg for Vec<T> {
219     const ARG_TYPE: ArgType = ArgType::Array;
signature() -> Signature<'static>220     fn signature() -> Signature<'static> { Signature::from(format!("a{}", T::signature())) }
221 }
222 
223 impl<T: Arg + Append> Append for Vec<T> {
append(self, i: &mut IterAppend)224     fn append(self, i: &mut IterAppend) {
225         Array::new(self).append(i);
226     }
227 }
228 
229 impl<'a, T: Arg + Get<'a>> Get<'a> for Vec<T> {
get(i: &mut Iter<'a>) -> Option<Self>230     fn get(i: &mut Iter<'a>) -> Option<Self> {
231         <Array<T, Iter<'a>>>::get(i).map(|a| a.collect())
232     }
233 }
234 
235 
236 #[derive(Copy, Clone, Debug)]
237 /// Represents a D-Bus Array. Maximum flexibility (wraps an iterator of items to append).
238 ///
239 /// See the argument guide and module level documentation for details and alternatives.
240 pub struct Array<'a, T, I>(I, PhantomData<(*const T, &'a Message)>);
241 
242 impl<'a, T: 'a, I: Iterator<Item=T>> Array<'a, T, I> {
243     /// Creates a new Array from an iterator. The iterator is consumed when appending.
new<J: IntoIterator<IntoIter=I, Item=T>>(j: J) -> Array<'a, T, I>244     pub fn new<J: IntoIterator<IntoIter=I, Item=T>>(j: J) -> Array<'a, T, I> { Array(j.into_iter(), PhantomData) }
245 }
246 
247 impl<'a, T: Arg, I> Arg for Array<'a, T, I> {
248     const ARG_TYPE: ArgType = ArgType::Array;
signature() -> Signature<'static>249     fn signature() -> Signature<'static> { Signature::from(format!("a{}", T::signature())) }
250 }
251 
252 impl<'a, T: 'a + Arg + Append, I: Iterator<Item=T>> Append for Array<'a, T, I> {
append(self, i: &mut IterAppend)253     fn append(self, i: &mut IterAppend) {
254         let z = self.0;
255         i.append_container(ArgType::Array, Some(T::signature().as_cstr()), |s| for arg in z { arg.append(s) });
256     }
257 }
258 
259 impl<'a, T: Arg + Get<'a>> Get<'a> for Array<'a, T, Iter<'a>> {
get(i: &mut Iter<'a>) -> Option<Array<'a, T, Iter<'a>>>260     fn get(i: &mut Iter<'a>) -> Option<Array<'a, T, Iter<'a>>> {
261         i.recurse(Self::ARG_TYPE).map(|si| Array(si, PhantomData))
262         // TODO: Verify full element signature?
263     }
264 }
265 
266 impl<'a, T: Get<'a>> Iterator for Array<'a, T, Iter<'a>> {
267     type Item = T;
next(&mut self) -> Option<T>268     fn next(&mut self) -> Option<T> {
269         let i = self.0.get();
270         self.0.next();
271         i
272     }
273 }
274 
275 // Due to the strong typing here; RefArg is implemented only for T's that are both Arg and RefArg.
276 // We need Arg for this to work for empty arrays (we can't get signature from first element if there is no elements).
277 // We need RefArg for non-consuming append.
278 impl<'a, T: 'a + Arg + fmt::Debug + RefArg, I: fmt::Debug + Clone + Iterator<Item=&'a T>> RefArg for Array<'static, T, I> {
arg_type(&self) -> ArgType279     fn arg_type(&self) -> ArgType { ArgType::Array }
signature(&self) -> Signature<'static>280     fn signature(&self) -> Signature<'static> { Signature::from(format!("a{}", <T as Arg>::signature())) }
append(&self, i: &mut IterAppend)281     fn append(&self, i: &mut IterAppend) {
282         let z = self.0.clone();
283         i.append_container(ArgType::Array, Some(<T as Arg>::signature().as_cstr()), |s|
284             for arg in z { (arg as &RefArg).append(s) }
285         );
286     }
287     #[inline]
as_any(&self) -> &any::Any where Self: 'static288     fn as_any(&self) -> &any::Any where Self: 'static { self }
289     #[inline]
as_any_mut(&mut self) -> &mut any::Any where Self: 'static290     fn as_any_mut(&mut self) -> &mut any::Any where Self: 'static { self }
291 
box_clone(&self) -> Box<RefArg + 'static>292     fn box_clone(&self) -> Box<RefArg + 'static> {
293         Box::new(InternalArray {
294             inner_sig: <T as Arg>::signature(),
295             data: self.0.clone().map(|x| x.box_clone()).collect(),
296         })
297     }
298 }
299 
get_fixed_array_refarg<'a, T: FixedArray + Clone + RefArg>(i: &mut Iter<'a>) -> Box<RefArg>300 fn get_fixed_array_refarg<'a, T: FixedArray + Clone + RefArg>(i: &mut Iter<'a>) -> Box<RefArg> {
301     let s = <&[T]>::get(i).unwrap();
302     Box::new(s.to_vec())
303 }
304 
get_var_array_refarg<'a, T: 'static + RefArg + Arg, F: FnMut(&mut Iter<'a>) -> Option<T>> (i: &mut Iter<'a>, mut f: F) -> Box<RefArg>305 fn get_var_array_refarg<'a, T: 'static + RefArg + Arg, F: FnMut(&mut Iter<'a>) -> Option<T>>
306     (i: &mut Iter<'a>, mut f: F) -> Box<RefArg> {
307     let mut v: Vec<T> = vec!(); // dbus_message_iter_get_element_count might be O(n), better not use it
308     let mut si = i.recurse(ArgType::Array).unwrap();
309     while let Some(q) = f(&mut si) { v.push(q); si.next(); }
310     Box::new(v)
311 }
312 
313 
314 #[derive(Debug)]
315 struct InternalDict<K> {
316    data: Vec<(K, Box<RefArg>)>,
317    outer_sig: Signature<'static>,
318 }
319 
get_dict_refarg<'a, K, F: FnMut(&mut Iter<'a>) -> Option<K>>(i: &mut Iter<'a>, mut f: F) -> Box<RefArg> where K: DictKey + 'static + RefArg + Clone320 fn get_dict_refarg<'a, K, F: FnMut(&mut Iter<'a>) -> Option<K>>(i: &mut Iter<'a>, mut f: F) -> Box<RefArg>
321     where K: DictKey + 'static + RefArg + Clone
322  {
323     let mut data = vec!();
324     let outer_sig = i.signature();
325     let mut si = i.recurse(ArgType::Array).unwrap();
326     while let Some(mut d) = si.recurse(ArgType::DictEntry) {
327         let k = f(&mut d).unwrap();
328         d.next();
329         data.push((k, d.get_refarg().unwrap()));
330         si.next();
331     }
332     Box::new(InternalDict { data, outer_sig })
333 }
334 
335 // This only happens from box_clone
336 impl RefArg for InternalDict<Box<RefArg>> {
arg_type(&self) -> ArgType337     fn arg_type(&self) -> ArgType { ArgType::Array }
signature(&self) -> Signature<'static>338     fn signature(&self) -> Signature<'static> { self.outer_sig.clone() }
append(&self, i: &mut IterAppend)339     fn append(&self, i: &mut IterAppend) {
340         let inner_sig = &self.outer_sig.as_cstr().to_bytes_with_nul()[1..];
341         let inner_sig = CStr::from_bytes_with_nul(inner_sig).unwrap();
342         i.append_container(ArgType::Array, Some(inner_sig), |s| for (k, v) in &self.data {
343             s.append_container(ArgType::DictEntry, None, |ss| {
344                 k.append(ss);
345                 v.append(ss);
346             })
347         });
348     }
349     #[inline]
as_any(&self) -> &any::Any where Self: 'static350     fn as_any(&self) -> &any::Any where Self: 'static { self }
351     #[inline]
as_any_mut(&mut self) -> &mut any::Any where Self: 'static352     fn as_any_mut(&mut self) -> &mut any::Any where Self: 'static { self }
as_iter<'b>(&'b self) -> Option<Box<Iterator<Item=&'b RefArg> + 'b>>353     fn as_iter<'b>(&'b self) -> Option<Box<Iterator<Item=&'b RefArg> + 'b>> {
354         Some(Box::new(self.data.iter().flat_map(|(k, v)| vec![k as &RefArg, v as &RefArg].into_iter())))
355     }
356     #[inline]
box_clone(&self) -> Box<RefArg + 'static>357     fn box_clone(&self) -> Box<RefArg + 'static> {
358         Box::new(InternalDict {
359             data: self.data.iter().map(|(k, v)| (k.box_clone(), v.box_clone())).collect(),
360             outer_sig: self.outer_sig.clone(),
361         })
362     }
363 }
364 
365 
366 impl<K: DictKey + RefArg + Clone + 'static> RefArg for InternalDict<K> {
arg_type(&self) -> ArgType367     fn arg_type(&self) -> ArgType { ArgType::Array }
signature(&self) -> Signature<'static>368     fn signature(&self) -> Signature<'static> { self.outer_sig.clone() }
append(&self, i: &mut IterAppend)369     fn append(&self, i: &mut IterAppend) {
370         let inner_sig = &self.outer_sig.as_cstr().to_bytes_with_nul()[1..];
371         let inner_sig = CStr::from_bytes_with_nul(inner_sig).unwrap();
372         i.append_container(ArgType::Array, Some(inner_sig), |s| for (k, v) in &self.data {
373             s.append_container(ArgType::DictEntry, None, |ss| {
374                 k.append(ss);
375                 v.append(ss);
376             })
377         });
378     }
379     #[inline]
as_any(&self) -> &any::Any where Self: 'static380     fn as_any(&self) -> &any::Any where Self: 'static { self }
381     #[inline]
as_any_mut(&mut self) -> &mut any::Any where Self: 'static382     fn as_any_mut(&mut self) -> &mut any::Any where Self: 'static { self }
as_iter<'b>(&'b self) -> Option<Box<Iterator<Item=&'b RefArg> + 'b>>383     fn as_iter<'b>(&'b self) -> Option<Box<Iterator<Item=&'b RefArg> + 'b>> {
384         Some(Box::new(self.data.iter().flat_map(|(k, v)| vec![k as &RefArg, v as &RefArg].into_iter())))
385     }
386     #[inline]
box_clone(&self) -> Box<RefArg + 'static>387     fn box_clone(&self) -> Box<RefArg + 'static> {
388         Box::new(InternalDict {
389             data: self.data.iter().map(|(k, v)| (k.clone(), v.box_clone())).collect(),
390             outer_sig: self.outer_sig.clone(),
391         })
392     }
393 }
394 
395 
396 // Fallback for Arrays of Arrays and Arrays of Structs.
397 // We store the signature manually here and promise that it is correct for all elements
398 // has that signature.
399 #[derive(Debug)]
400 struct InternalArray {
401    data: Vec<Box<RefArg>>,
402    inner_sig: Signature<'static>,
403 }
404 
get_internal_array<'a>(i: &mut Iter<'a>) -> Box<RefArg>405 fn get_internal_array<'a>(i: &mut Iter<'a>) -> Box<RefArg> {
406     let mut si = i.recurse(ArgType::Array).unwrap();
407     let inner_sig = si.signature();
408     let data = si.collect::<Vec<_>>();
409     Box::new(InternalArray { data, inner_sig })
410 }
411 
412 impl RefArg for InternalArray {
arg_type(&self) -> ArgType413     fn arg_type(&self) -> ArgType { ArgType::Array }
signature(&self) -> Signature<'static>414     fn signature(&self) -> Signature<'static> { Signature::from(format!("a{}", self.inner_sig)) }
append(&self, i: &mut IterAppend)415     fn append(&self, i: &mut IterAppend) {
416         i.append_container(ArgType::Array, Some(self.inner_sig.as_cstr()), |s|
417             for arg in &self.data { (arg as &RefArg).append(s) }
418         );
419     }
420     #[inline]
as_any(&self) -> &any::Any where Self: 'static421     fn as_any(&self) -> &any::Any where Self: 'static { self }
422     #[inline]
as_any_mut(&mut self) -> &mut any::Any where Self: 'static423     fn as_any_mut(&mut self) -> &mut any::Any where Self: 'static { self }
as_iter<'a>(&'a self) -> Option<Box<Iterator<Item=&'a RefArg> + 'a>>424     fn as_iter<'a>(&'a self) -> Option<Box<Iterator<Item=&'a RefArg> + 'a>> {
425         Some(Box::new(self.data.iter().map(|b| b as &RefArg)))
426     }
427     #[inline]
box_clone(&self) -> Box<RefArg + 'static>428     fn box_clone(&self) -> Box<RefArg + 'static> {
429         Box::new(InternalArray {
430             data: self.data.iter().map(|x| x.box_clone()).collect(),
431             inner_sig: self.inner_sig.clone(),
432         })
433     }
434 }
435 
get_array_refarg<'a>(i: &mut Iter<'a>) -> Box<RefArg>436 pub fn get_array_refarg<'a>(i: &mut Iter<'a>) -> Box<RefArg> {
437     debug_assert!(i.arg_type() == ArgType::Array);
438     let etype = ArgType::from_i32(unsafe { ffi::dbus_message_iter_get_element_type(&mut i.0) } as i32).unwrap();
439 
440     let x = match etype {
441         ArgType::Byte => get_fixed_array_refarg::<u8>(i),
442         ArgType::Int16 => get_fixed_array_refarg::<i16>(i),
443         ArgType::UInt16 => get_fixed_array_refarg::<u16>(i),
444         ArgType::Int32 => get_fixed_array_refarg::<i32>(i),
445         ArgType::UInt32 => get_fixed_array_refarg::<u32>(i),
446         ArgType::Int64 => get_fixed_array_refarg::<i64>(i),
447         ArgType::UInt64 => get_fixed_array_refarg::<u64>(i),
448         ArgType::Double => get_fixed_array_refarg::<f64>(i),
449 	ArgType::String => get_var_array_refarg::<String, _>(i, |si| si.get()),
450 	ArgType::ObjectPath => get_var_array_refarg::<Path<'static>, _>(i, |si| si.get::<Path>().map(|s| s.into_static())),
451 	ArgType::Signature => get_var_array_refarg::<Signature<'static>, _>(i, |si| si.get::<Signature>().map(|s| s.into_static())),
452 	ArgType::Variant => get_var_array_refarg::<Variant<Box<RefArg>>, _>(i, |si| Variant::new_refarg(si)),
453 	ArgType::Boolean => get_var_array_refarg::<bool, _>(i, |si| si.get()),
454 	ArgType::Invalid => panic!("Array with Invalid ArgType"),
455         ArgType::Array => get_internal_array(i),
456         ArgType::DictEntry => {
457             let key = ArgType::from_i32(i.signature().as_bytes()[2] as i32).unwrap(); // The third character, after "a{", is our key.
458             match key {
459                 ArgType::Byte => get_dict_refarg::<u8, _>(i, |si| si.get()),
460                 ArgType::Int16 => get_dict_refarg::<i16, _>(i, |si| si.get()),
461                 ArgType::UInt16 => get_dict_refarg::<u16, _>(i, |si| si.get()),
462                 ArgType::Int32 => get_dict_refarg::<i32, _>(i, |si| si.get()),
463                 ArgType::UInt32 => get_dict_refarg::<u32, _>(i, |si| si.get()),
464                 ArgType::Int64 => get_dict_refarg::<i64, _>(i, |si| si.get()),
465                 ArgType::UInt64 => get_dict_refarg::<u64, _>(i, |si| si.get()),
466                 ArgType::Double => get_dict_refarg::<f64, _>(i, |si| si.get()),
467                 ArgType::Boolean => get_dict_refarg::<bool, _>(i, |si| si.get()),
468                 // ArgType::UnixFd => get_dict_refarg::<OwnedFd, _>(i, |si| si.get()),
469                 ArgType::String => get_dict_refarg::<String, _>(i, |si| si.get()),
470                 ArgType::ObjectPath => get_dict_refarg::<Path<'static>, _>(i, |si| si.get::<Path>().map(|s| s.into_static())),
471                 ArgType::Signature => get_dict_refarg::<Signature<'static>, _>(i, |si| si.get::<Signature>().map(|s| s.into_static())),
472                 _ => panic!("Array with invalid dictkey ({:?})", key),
473             }
474         }
475         ArgType::UnixFd => get_var_array_refarg::<OwnedFd, _>(i, |si| si.get()),
476         ArgType::Struct => get_internal_array(i),
477     };
478 
479     debug_assert_eq!(i.signature(), x.signature());
480     x
481 }
482 
483 
484