1use std::ops::DerefMut;
3use std::cell::RefCell;
4
5use dbus_serialize::types::{Path,Variant,Value,BasicValue,Signature};
6
7use marshal::{Marshal,pad_to_multiple};
8use demarshal::{demarshal,DemarshalError};
9
10#[derive(Debug,Default,PartialEq,Eq)]
11pub struct MessageType(pub u8);
12pub const MESSAGE_TYPE_INVALID : MessageType = MessageType(0);
13pub const MESSAGE_TYPE_METHOD_CALL : MessageType = MessageType(1);
14pub const MESSAGE_TYPE_METHOD_RETURN : MessageType = MessageType(2);
15pub const MESSAGE_TYPE_ERROR : MessageType = MessageType(3);
16pub const MESSAGE_TYPE_SIGNAL : MessageType = MessageType(4);
17
18pub const HEADER_FIELD_INVALID : u8 = 0;
19pub const HEADER_FIELD_PATH: u8 = 1;
20pub const HEADER_FIELD_INTERFACE: u8 = 2;
21pub const HEADER_FIELD_MEMBER: u8 = 3;
22pub const HEADER_FIELD_ERROR_NAME: u8 = 4;
23pub const HEADER_FIELD_REPLY_SERIAL: u8 = 5;
24pub const HEADER_FIELD_DESTINATION: u8 = 6;
25pub const HEADER_FIELD_SENDER: u8 = 7;
26pub const HEADER_FIELD_SIGNATURE: u8 = 8;
27
28pub const FLAGS_NO_REPLY_EXPECTED : u8 = 1;
29
30#[derive(Debug)]
31pub struct HeaderField (
32 pub u8,
33 pub Variant
34);
35
36impl Marshal for HeaderField {
37 fn dbus_encode(&self, buf: &mut Vec<u8>) -> usize {
38 pad_to_multiple(buf, 8);
39 let start_len = buf.len();
40 let code = self.0 as u8;
41 code.dbus_encode(buf);
42 self.1.dbus_encode(buf);
43 buf.len() - start_len
44 }
45 fn get_type(&self) -> String {
46 "(yv)".to_owned()
47 }
48}
49
50#[derive(Debug,Default)]
52pub struct Message {
53 pub big_endian: bool,
54 pub message_type: MessageType,
55 pub flags: u8,
56 pub version: u8,
57 pub serial: u32,
58 pub headers: Vec<HeaderField>,
59 pub body: Vec<u8>,
60
61 body_cache: RefCell<Option<Result<Option<Vec<Value>>, DemarshalError>>>
62}
63
64impl Marshal for Message {
65 fn dbus_encode (&self, buf: &mut Vec<u8>) -> usize {
66 let endian = if self.big_endian { 'B' as u8 } else { 'l' as u8 };
67 endian.dbus_encode(buf);
68 self.message_type.0.dbus_encode(buf);
69 self.flags.dbus_encode(buf);
70 self.version.dbus_encode(buf);
71 let len : u32 = self.body.len() as u32;
72 len.dbus_encode(buf);
73 self.serial.dbus_encode(buf);
74 self.headers.dbus_encode(buf);
75 pad_to_multiple(buf, 8);
76 0
77 }
78
79 fn get_type (&self) -> String {
80 panic!("Don't do that.")
81 }
82}
83
84pub fn create_method_call (dest: &str, path: &str, iface: &str, method: &str) -> Message {
87 Message {
88 big_endian: false,
89 message_type: MESSAGE_TYPE_METHOD_CALL,
90 flags: 0,
91 version: 1,
92 serial: 0,
93 headers: Vec::new(),
94 body: Vec::new(),
95
96 body_cache: RefCell::new(None),
97 }.add_header(HEADER_FIELD_DESTINATION,
98 Variant::new(Value::from(dest), "s"))
99 .add_header(HEADER_FIELD_PATH,
100 Variant::new(Value::BasicValue(BasicValue::ObjectPath(Path(path.to_owned()))), "o"))
101 .add_header(HEADER_FIELD_INTERFACE,
102 Variant::new(Value::from(iface), "s"))
103 .add_header(HEADER_FIELD_MEMBER,
104 Variant::new(Value::from(method), "s"))
105}
106
107pub fn create_method_return(reply_serial: u32) -> Message {
110 Message {
111 big_endian: false,
112 message_type: MESSAGE_TYPE_METHOD_RETURN,
113 flags: 0,
114 version: 1,
115 serial: 0,
116 headers: Vec::new(),
117 body: Vec::new(),
118
119 body_cache: RefCell::new(None),
120 }.add_header(HEADER_FIELD_REPLY_SERIAL,
121 Variant::new(Value::from(reply_serial), "u"))
122}
123
124pub fn create_error(error_name: &str, reply_serial: u32) -> Message {
127 Message {
128 big_endian: false,
129 message_type: MESSAGE_TYPE_ERROR,
130 flags: 0,
131 version: 1,
132 serial: 0,
133 headers: Vec::new(),
134 body: Vec::new(),
135
136 body_cache: RefCell::new(None),
137 }.add_header(HEADER_FIELD_REPLY_SERIAL,
138 Variant::new(Value::from(reply_serial), "u"))
139 .add_header(HEADER_FIELD_ERROR_NAME,
140 Variant::new(Value::from(error_name), "s"))
141}
142
143pub fn create_signal(path: &str, interface: &str, member: &str) -> Message {
146 Message {
147 big_endian: false,
148 message_type: MESSAGE_TYPE_SIGNAL,
149 flags: 0,
150 version: 1,
151 serial: 0,
152 headers: Vec::new(),
153 body: Vec::new(),
154
155 body_cache: RefCell::new(None),
156 }.add_header(HEADER_FIELD_PATH,
157 Variant::new(Value::BasicValue(BasicValue::ObjectPath(Path(path.to_owned()))), "o"))
158 .add_header(HEADER_FIELD_INTERFACE,
159 Variant::new(Value::from(interface), "s"))
160 .add_header(HEADER_FIELD_MEMBER,
161 Variant::new(Value::from(member), "s"))
162}
163
164impl Message {
165 pub fn add_arg(mut self, arg: &Marshal) -> Message {
178 if let None = self.get_header(HEADER_FIELD_SIGNATURE) {
179 let value = Value::BasicValue(BasicValue::Signature(Signature("".to_owned())));
180 let variant = Variant::new(value, "g");
181 self = self.add_header(HEADER_FIELD_SIGNATURE, variant);
182 };
183 {
184 let b : &mut Box<Value> = &mut self.get_header_mut(HEADER_FIELD_SIGNATURE).unwrap().object;
185 let val : &mut Value = b.deref_mut();
186 match *val {
187 Value::BasicValue(BasicValue::Signature(ref mut s)) => s.0.push_str(&arg.get_type()),
188 _ => panic!("Garbage in signature field")
189 };
190 }
191 arg.dbus_encode(&mut self.body);
192 self
193 }
194
195 pub fn get_header(&self, name: u8) -> Option<&Variant> {
196 self.headers.iter().position(|x| { x.0 == name })
197 .map(|idx| &self.headers[idx].1)
198 }
199
200 pub fn get_header_mut(&mut self, name: u8) -> Option<&mut Variant> {
201 match self.headers.iter().position(|x| { x.0 == name }) {
202 Some(idx) => Some(&mut self.headers[idx].1),
203 _ => None
204 }
205 }
206
207 pub fn add_header(mut self, name: u8, val: Variant) -> Message {
208 self.headers.push(HeaderField (name, val));
209 self
210 }
211
212 pub fn get_body(&self) -> Result<Option<Vec<Value>>,DemarshalError> {
215 if self.body.is_empty() {
216 return Ok(None);
217 }
218 let cached = self.body_cache.borrow().is_some();
219 if !cached {
220 let v = match self.headers.iter().position(|x| { x.0 == HEADER_FIELD_SIGNATURE }) {
222 Some(idx) => &self.headers[idx].1,
223 None => return Ok(None)
224 };
225
226 let sigval = match *v.object {
227 Value::BasicValue(BasicValue::Signature(ref x)) => x,
228 _ => return Ok(None)
229 };
230
231 let mut body = self.body.clone();
232 let mut sig = "(".to_owned() + &sigval.0 + ")";
233 let mut offset = 0;
234 *self.body_cache.borrow_mut() = Some((|| {
235 match try!(demarshal(&mut body, &mut offset, &mut sig)) {
236 Value::Struct(x) => Ok(Some(x.objects)),
237 x => panic!("Didn't get a struct: {:?}", x)
238 }
239 })());
240 }
241 self.body_cache.borrow().as_ref().unwrap().clone()
242 }
243}
244
245#[test]
246fn test_msg () {
247 create_method_call("foo", "bar", "baz", "floob")
248 .add_arg(&1)
249 .add_arg(&2);
250}