1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
use crate::params;
use crate::signature;
use crate::wire::unmarshal::Error;
use crate::wire::unmarshal::UnmarshalContext;
use crate::wire::unmarshal::UnmarshalResult;
use crate::wire::util::*;
pub fn unmarshal_base<'a>(
typ: signature::Base,
ctx: &mut UnmarshalContext,
) -> UnmarshalResult<params::Base<'a>> {
let padding = ctx.align_to(typ.get_alignment())?;
let (bytes, param) = match typ {
signature::Base::Byte => {
if ctx.offset >= ctx.buf.len() {
return Err(Error::NotEnoughBytes);
}
Ok((1, params::Base::Byte(ctx.buf[ctx.offset])))
}
signature::Base::Uint16 => {
let slice = &ctx.buf[ctx.offset..];
let (bytes, val) = parse_u16(slice, ctx.byteorder)?;
Ok((bytes, params::Base::Uint16(val)))
}
signature::Base::Int16 => {
let slice = &ctx.buf[ctx.offset..];
let (bytes, val) = parse_u16(slice, ctx.byteorder)?;
Ok((bytes, params::Base::Int16(val as i16)))
}
signature::Base::Uint32 => {
let slice = &ctx.buf[ctx.offset..];
let (bytes, val) = parse_u32(slice, ctx.byteorder)?;
Ok((bytes, params::Base::Uint32(val)))
}
signature::Base::UnixFd => {
let slice = &ctx.buf[ctx.offset..];
let (bytes, idx) = parse_u32(slice, ctx.byteorder)?;
if ctx.fds.len() <= idx as usize {
Err(crate::wire::unmarshal::Error::BadFdIndex(idx as usize))
} else {
let val = &ctx.fds[idx as usize];
Ok((bytes, params::Base::UnixFd(val.clone())))
}
}
signature::Base::Int32 => {
let slice = &ctx.buf[ctx.offset..];
let (bytes, val) = parse_u32(slice, ctx.byteorder)?;
Ok((bytes, params::Base::Int32(val as i32)))
}
signature::Base::Uint64 => {
let slice = &ctx.buf[ctx.offset..];
let (bytes, val) = parse_u64(slice, ctx.byteorder)?;
Ok((bytes, params::Base::Uint64(val)))
}
signature::Base::Int64 => {
let slice = &ctx.buf[ctx.offset..];
let (bytes, val) = parse_u64(slice, ctx.byteorder)?;
Ok((bytes, params::Base::Int64(val as i64)))
}
signature::Base::Double => {
let slice = &ctx.buf[ctx.offset..];
let (bytes, val) = parse_u64(slice, ctx.byteorder)?;
Ok((bytes, params::Base::Double(val)))
}
signature::Base::Boolean => {
let slice = &ctx.buf[ctx.offset..];
let (bytes, val) = parse_u32(slice, ctx.byteorder)?;
match val {
0 => Ok((bytes, params::Base::Boolean(false))),
1 => Ok((bytes, params::Base::Boolean(true))),
_ => Err(Error::InvalidBoolean),
}
}
signature::Base::String => {
let (bytes, string) = unmarshal_string(ctx.byteorder, &ctx.buf[ctx.offset..])?;
Ok((bytes, params::Base::String(string)))
}
signature::Base::ObjectPath => {
let (bytes, string) = unmarshal_string(ctx.byteorder, &ctx.buf[ctx.offset..])?;
crate::params::validate_object_path(&string)?;
Ok((bytes, params::Base::ObjectPath(string)))
}
signature::Base::Signature => {
let (bytes, string) = unmarshal_signature(&ctx.buf[ctx.offset..])?;
crate::params::validate_signature(&string)?;
Ok((bytes, params::Base::Signature(string.to_owned())))
}
}?;
ctx.offset += bytes;
Ok((padding + bytes, param))
}