async_rustbus/rustbus_core/message_builder/
mod.rs1use std::convert::TryInto;
4use std::num::NonZeroU32;
5
6use super::wire::marshal::traits::{Marshal, Signature, SignatureBuffer};
7use super::wire::marshal::MarshalContext;
8use super::wire::unmarshal::{traits::Unmarshal, UnmarshalContext, HEADER_LEN};
9use crate::utils::align_num;
10
11pub use super::org_message_builder::{HeaderFlags, MessageType};
12use super::path::ObjectPath;
13use super::signature::{Base, Container, Type};
14use super::ByteOrder;
15
16use rustbus::params::validation::Error as ValidationErr;
17use rustbus::params::validation::{
18 validate_busname, validate_errorname, validate_interface, validate_membername,
19 validate_signature,
20};
21use rustbus::wire::util::{insert_u32, unmarshal_signature, write_signature};
22
23mod body;
24
25pub use body::{MarshalledMessageBody, MessageBodyParser};
26
27#[derive(Default)]
29pub struct MessageBuilder {
30 msg: MarshalledMessage,
31}
32
33pub struct CallBuilder {
35 msg: MarshalledMessage,
36}
37
38pub struct SignalBuilder {
40 msg: MarshalledMessage,
41}
42
43impl MessageBuilder {
44 pub fn new() -> MessageBuilder {
46 MessageBuilder {
47 msg: MarshalledMessage::new(),
48 }
49 }
50
51 pub fn with_byteorder(b: ByteOrder) -> MessageBuilder {
53 MessageBuilder {
54 msg: MarshalledMessage::with_byteorder(b),
55 }
56 }
57
58 pub fn call<S: Into<String>>(mut self, member: S) -> CallBuilder {
59 self.msg.typ = MessageType::Call;
60 self.msg.dynheader.member = Some(member.into());
61 CallBuilder { msg: self.msg }
62 }
63 pub fn signal<S1, S2, S3>(mut self, interface: S1, member: S2, object: S3) -> SignalBuilder
64 where
65 S1: Into<String>,
66 S2: Into<String>,
67 S3: Into<String>,
68 {
69 self.msg.typ = MessageType::Signal;
70 self.msg.dynheader.member = Some(member.into());
71 self.msg.dynheader.interface = Some(interface.into());
72 self.msg.dynheader.object = Some(object.into());
73 SignalBuilder { msg: self.msg }
74 }
75}
76
77impl CallBuilder {
78 pub fn on<S: Into<String>>(mut self, object_path: S) -> Self {
79 self.msg.dynheader.object = Some(object_path.into());
80 self
81 }
82
83 pub fn with_interface<S: Into<String>>(mut self, interface: S) -> Self {
84 self.msg.dynheader.interface = Some(interface.into());
85 self
86 }
87
88 pub fn at<S: Into<String>>(mut self, destination: S) -> Self {
89 self.msg.dynheader.destination = Some(destination.into());
90 self
91 }
92
93 pub fn build(self) -> MarshalledMessage {
94 self.msg
95 }
96}
97
98impl SignalBuilder {
99 pub fn to<S: Into<String>>(mut self, destination: S) -> Self {
100 self.msg.dynheader.destination = Some(destination.into());
101 self
102 }
103
104 pub fn build(self) -> MarshalledMessage {
105 self.msg
106 }
107}
108
109#[derive(Debug)]
116pub struct MarshalledMessage {
117 pub body: MarshalledMessageBody,
118
119 pub dynheader: DynamicHeader,
120
121 pub typ: MessageType,
122 pub flags: u8,
123}
124
125impl Default for MarshalledMessage {
126 fn default() -> Self {
127 Self::new()
128 }
129}
130
131impl MarshalledMessage {
132 pub fn get_buf(&self) -> &[u8] {
133 self.body.buf()
134 }
135 pub fn get_sig(&self) -> &str {
136 self.body.sig()
137 }
138
139 pub fn new() -> Self {
141 MarshalledMessage {
142 typ: MessageType::Invalid,
143 dynheader: DynamicHeader::default(),
144
145 flags: 0,
146 body: MarshalledMessageBody::new(),
147 }
148 }
149
150 pub fn with_byteorder(b: ByteOrder) -> Self {
152 MarshalledMessage {
153 typ: MessageType::Invalid,
154 dynheader: DynamicHeader::default(),
155
156 flags: 0,
157 body: MarshalledMessageBody::with_byteorder(b),
158 }
159 }
160
161 pub fn reserve(&mut self, additional: usize) {
164 self.body.reserve(additional)
165 }
166 pub fn marshal_header(
167 &self,
168 serial: NonZeroU32,
169 hdr_buf: &mut Vec<u8>,
170 ) -> Result<(), super::Error> {
171 hdr_buf.clear();
172 let mut _fds = Vec::new();
173 let mut ctx = MarshalContext {
174 byteorder: self.body.byteorder(),
175 fds: &mut _fds,
176 buf: hdr_buf,
177 };
178 let bo_byte: u8 = match ctx.byteorder {
179 ByteOrder::LittleEndian => b'l',
180 ByteOrder::BigEndian => b'B',
181 };
182 bo_byte.marshal(&mut ctx).unwrap();
183 let t_byte: u8 = match self.typ {
184 MessageType::Invalid => 0,
185 MessageType::Call => 1,
186 MessageType::Reply => 2,
187 MessageType::Error => 3,
188 MessageType::Signal => 4,
189 };
190 t_byte.marshal(&mut ctx).unwrap();
191 self.flags.marshal(&mut ctx).unwrap();
192 1u8.marshal(&mut ctx).unwrap();
193 (self.body.buf().len() as u32).marshal(&mut ctx).unwrap();
194 u32::from(serial).marshal(&mut ctx).unwrap();
195 0u32.marshal(&mut ctx).unwrap();
196 if let Some(obj) = &self.dynheader.object {
197 let path = ObjectPath::from_str(obj)
198 .map_err(|_| super::Error::Validation(ValidationErr::InvalidObjectPath))?;
199 (1u8, HdrVar::Path(path)).marshal(&mut ctx).unwrap();
200 }
201 if let Some(iface) = &self.dynheader.interface {
202 validate_interface(iface)?;
203 (2u8, HdrVar::Str(iface)).marshal(&mut ctx).unwrap();
204 }
205 if let Some(member) = &self.dynheader.member {
206 validate_membername(member)?;
207 (3u8, HdrVar::Str(member)).marshal(&mut ctx).unwrap();
208 }
209 if let Some(err) = &self.dynheader.error_name {
210 validate_errorname(err)?;
211 (4u8, HdrVar::Str(err)).marshal(&mut ctx).unwrap();
212 }
213 if let Some(rsp_idx) = &self.dynheader.response_serial {
214 (5u8, HdrVar::U32((*rsp_idx).into()))
215 .marshal(&mut ctx)
216 .unwrap();
217 }
218 if let Some(dest) = &self.dynheader.destination {
219 validate_busname(dest)?;
220 (6u8, HdrVar::Str(dest)).marshal(&mut ctx).unwrap();
221 }
222 if let Some(sender) = &self.dynheader.sender {
223 validate_busname(sender)?;
224 (7u8, HdrVar::Str(sender)).marshal(&mut ctx).unwrap();
225 }
226 if !self.body.buf().is_empty() {
227 let sig = self.body.sig();
228 debug_assert!(SigStr::new(sig).is_ok());
229 let ss = unsafe { SigStr::new_no_val(sig) };
230 (8u8, HdrVar::Sig(ss)).marshal(&mut ctx).unwrap();
231 }
232 let fd_cnt = self.body.fds().len() as u32;
233 if fd_cnt != 0 {
234 (9u8, HdrVar::U32(fd_cnt)).marshal(&mut ctx).unwrap();
235 }
236 let len = ctx.buf.len() - (HEADER_LEN + 4);
237 insert_u32(ctx.byteorder, len as u32, &mut ctx.buf[HEADER_LEN..]);
238 ctx.align_to(8);
239 Ok(())
240 }
241}
242
243#[derive(Debug, Clone, Default)]
245pub struct DynamicHeader {
246 pub interface: Option<String>,
247 pub member: Option<String>,
248 pub object: Option<String>,
249 pub destination: Option<String>,
250 pub serial: Option<NonZeroU32>,
251 pub sender: Option<String>,
252 pub signature: Option<String>,
253 pub error_name: Option<String>,
254 pub response_serial: Option<NonZeroU32>,
255 pub num_fds: Option<u32>,
256}
257
258impl DynamicHeader {
259 pub fn make_error_response<S: Into<String>>(
261 &self,
262 error_name: S,
263 error_msg: Option<String>,
264 ) -> MarshalledMessage {
265 let mut err_resp = MarshalledMessage {
266 typ: MessageType::Error,
267 dynheader: DynamicHeader {
268 interface: None,
269 member: None,
270 object: None,
271 destination: self.sender.clone(),
272 serial: None,
273 num_fds: None,
274 sender: None,
275 signature: None,
276 response_serial: self.serial,
277 error_name: Some(error_name.into()),
278 },
279 flags: 0,
280 body: MarshalledMessageBody::new(),
281 };
282 if let Some(text) = error_msg {
283 err_resp.body.push_param(text).unwrap();
284 }
285 err_resp
286 }
287 pub fn make_response(&self) -> MarshalledMessage {
289 MarshalledMessage {
290 typ: MessageType::Reply,
291 dynheader: DynamicHeader {
292 interface: None,
293 member: None,
294 object: None,
295 destination: self.sender.clone(),
296 serial: None,
297 num_fds: None,
298 sender: None,
299 signature: None,
300 response_serial: self.serial,
301 error_name: None,
302 },
303 flags: 0,
304 body: MarshalledMessageBody::new(),
305 }
306 }
307 pub fn validate(&self) -> bool {
308 if let Some(iface) = &self.interface {
309 if validate_interface(iface).is_err() {
310 return false;
311 }
312 }
313 if let Some(path) = &self.object {
314 if ObjectPath::from_str(path).is_err() {
315 return false;
316 }
317 }
318 if let Some(member) = &self.member {
319 if validate_membername(member).is_err() {
320 return false;
321 }
322 }
323 if let Some(err) = &self.error_name {
324 if validate_errorname(err).is_err() {
325 return false;
326 }
327 }
328 if let Some(dest) = &self.destination {
329 if validate_busname(dest).is_err() {
330 return false;
331 }
332 }
333 if let Some(sender) = &self.sender {
334 if validate_busname(sender).is_err() {
335 return false;
336 }
337 }
338 if let Some(sig) = &self.signature {
339 if validate_signature(sig).is_err() {
340 return false;
341 }
342 }
343 true
344 }
345}
346impl Signature for DynamicHeader {
347 fn signature() -> super::signature::Type {
348 Type::Container(Container::Dict(
349 Base::Byte,
350 Box::new(Type::Container(Container::Variant)),
351 ))
352 }
353 fn alignment() -> usize {
354 4
355 }
356}
357
358use super::wire::unmarshal;
359impl<'buf, 'fds> Unmarshal<'buf, 'fds> for DynamicHeader {
360 fn unmarshal(ctx: &mut UnmarshalContext<'fds, 'buf>) -> unmarshal::UnmarshalResult<Self> {
361 let start = ctx.offset;
362 let (_, len) = u32::unmarshal(ctx)?;
363 let len = len as usize;
364
365 let end = align_num(ctx.offset + len, 8);
366 if end > ctx.buf.len() {
367 return Err(unmarshal::Error::NotEnoughBytes);
368 }
369 let mut fields: [Option<HdrVar>; 10] = Default::default();
370 let mut array_used = 0;
371 while array_used < len {
372 let (u, (idx, var)) = <(u8, HdrVar)>::unmarshal(ctx)?;
373 fields[idx as usize] = Some(var);
374 array_used += u;
375 }
376 if array_used != len {
377 return Err(unmarshal::Error::NotEnoughBytesForCollection);
378 }
379 let mut ret = DynamicHeader::default();
380 if let Some(var) = &fields[1] {
381 match var {
382 HdrVar::Path(p) => ret.object = Some(p.to_string()),
383 _ => return Err(unmarshal::Error::InvalidHeaderField),
384 }
385 }
386 if let Some(var) = &fields[2] {
387 match var {
388 HdrVar::Str(p) => ret.interface = Some(p.to_string()),
389 _ => return Err(unmarshal::Error::InvalidHeaderField),
390 }
391 }
392 if let Some(var) = &fields[3] {
393 match var {
394 HdrVar::Str(p) => ret.member = Some(p.to_string()),
395 _ => return Err(unmarshal::Error::InvalidHeaderField),
396 }
397 }
398 if let Some(var) = &fields[4] {
399 match var {
400 HdrVar::Str(p) => ret.error_name = Some(p.to_string()),
401 _ => return Err(unmarshal::Error::InvalidHeaderField),
402 }
403 }
404 if let Some(var) = &fields[5] {
405 match var {
406 HdrVar::U32(p) if *p != 0 => ret.response_serial = Some((*p).try_into().unwrap()),
407 _ => return Err(unmarshal::Error::InvalidHeaderField),
408 }
409 }
410 if let Some(var) = &fields[6] {
411 match var {
412 HdrVar::Str(p) => ret.destination = Some(p.to_string()),
413 _ => return Err(unmarshal::Error::InvalidHeaderField),
414 }
415 }
416 if let Some(var) = &fields[7] {
417 match var {
418 HdrVar::Str(p) => ret.sender = Some(p.to_string()),
419 _ => return Err(unmarshal::Error::InvalidHeaderField),
420 }
421 }
422 if let Some(var) = &fields[8] {
423 match var {
424 HdrVar::Sig(p) => ret.signature = Some(p.to_string()),
425 _ => return Err(unmarshal::Error::InvalidHeaderField),
426 }
427 }
428 if let Some(var) = &fields[9] {
429 match var {
430 HdrVar::U32(p) => ret.num_fds = Some(*p),
431 _ => return Err(unmarshal::Error::InvalidHeaderField),
432 }
433 }
434 if !ret.validate() {
435 Err(unmarshal::Error::InvalidHeaderField)
436 } else {
437 ctx.align_to(8)?;
438 Ok((ctx.offset - start, ret))
439 }
440 }
441}
442
443#[derive(Debug)]
444#[doc(hidden)]
445pub struct SigStr(str);
446
447impl SigStr {
448 fn new(sig: &str) -> Result<&Self, ValidationErr> {
449 validate_signature(sig)?;
450 Ok(unsafe { Self::new_no_val(sig) })
451 }
452 unsafe fn new_no_val(sig: &str) -> &Self {
453 &*(sig as *const str as *const SigStr)
454 }
455}
456use std::ops::Deref;
457impl Deref for SigStr {
458 type Target = str;
459 fn deref(&self) -> &Self::Target {
460 &self.0
461 }
462}
463
464impl Signature for &SigStr {
465 fn signature() -> Type {
466 Type::Base(Base::Signature)
467 }
468 fn alignment() -> usize {
469 Self::signature().get_alignment()
470 }
471 fn sig_str(s_buf: &mut SignatureBuffer) {
472 s_buf.push_static("g");
473 }
474}
475impl<'buf, 'fds> Unmarshal<'buf, 'fds> for &'buf SigStr {
476 fn unmarshal(ctx: &mut UnmarshalContext<'fds, 'buf>) -> unmarshal::UnmarshalResult<Self> {
477 let (used, sig) = unmarshal_signature(&ctx.buf[ctx.offset..])?;
478 ctx.offset += used;
479 let ret = SigStr::new(sig)?;
480 Ok((used, ret))
481 }
482}
483impl Marshal for &SigStr {
484 fn marshal(&self, ctx: &mut MarshalContext) -> Result<(), super::Error> {
485 write_signature(&self.0, ctx.buf);
486 Ok(())
487 }
488}
489
490use super::dbus_variant_var;
491dbus_variant_var!(HdrVar, Path => &'buf ObjectPath; Str => &'buf str; U32 => u32; Sig => &'buf SigStr);