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