dbus_message_parser/decode/message/
message_struct.rs

1use crate::decode::{DecodeError, DecodeResult, Decoder};
2use crate::message::Message;
3use crate::value::{Type, Value};
4use bytes::Bytes;
5#[cfg(target_family = "unix")]
6use std::os::unix::io::RawFd;
7
8impl<'a> Decoder<'a> {
9    fn message_body(
10        &mut self,
11        is_le: bool,
12        length: u32,
13        signature: &[Type],
14    ) -> DecodeResult<Vec<Value>> {
15        let end = Decoder::<'a>::checked_add(self.offset, length as usize)?;
16        let body = self.values(is_le, 0, signature)?;
17        if end == self.offset {
18            Ok(body)
19        } else {
20            Err(DecodeError::BodyLength(end, self.offset))
21        }
22    }
23
24    /// Decode a byte array to a `Message` object.
25    ///
26    /// # Example
27    /// ```
28    /// # use bytes::Bytes;
29    /// # use dbus_message_parser::message::Message;
30    /// let msg = b"l\x02\x01\x01\n\0\0\0\x01\0\0\0=\0\0\0\x06\x01s\0\x05\0\0\0:1.98\0\0\0\x05\x01u\0\x01\0\0\0\x08\x01g\0\x01s\0\0\x07\x01s\0\x14\0\0\0org.freedesktop.DBus\0\0\0\0\x05\0\0\0:1.98\0";
31    /// let buf_read = Bytes::copy_from_slice(&msg[..]);
32    ///
33    /// if let Ok(msg) = Message::decode(buf_read) {
34    ///     //...
35    /// }
36    /// ```
37    pub(crate) fn message(&mut self) -> DecodeResult<Message> {
38        let (header, body) = self.message_header()?;
39
40        self.algin(8)?;
41
42        let body = match body {
43            Some((body_length, body_signature)) => {
44                self.message_body(header.is_le, body_length, &body_signature)?
45            }
46            None => Vec::new(),
47        };
48
49        Ok(Message::new(header, body))
50    }
51}
52
53impl Message {
54    /// The decode a [`Message`] and returns the offset.
55    pub fn decode(bytes: Bytes) -> DecodeResult<(Message, usize)> {
56        let mut decoder = Decoder::new(bytes);
57        let msg = decoder.message()?;
58        let offset = decoder.offset;
59        Ok((msg, offset))
60    }
61
62    /// The decode a [`Message`] and returns the offset and the offset of the given FDs.
63    #[cfg(target_family = "unix")]
64    pub fn decode_with_fds(bytes: Bytes, fds: &[RawFd]) -> DecodeResult<(Message, usize, usize)> {
65        let mut decoder = Decoder::new_with_fds(bytes, fds);
66        let msg = decoder.message()?;
67        let offset = decoder.offset;
68        let offset_fds = match decoder.offset_fds {
69            Some(offset_fds) => offset_fds + 1,
70            None => 0,
71        };
72        Ok((msg, offset, offset_fds))
73    }
74}
75
76#[test]
77fn message_body_error() {
78    let b = Bytes::from_static(b"\xff");
79    let type_ = Type::Byte;
80    let mut decoder = Decoder::new(b);
81    assert_eq!(
82        decoder.message_body(true, 2, &[type_]),
83        Err(DecodeError::BodyLength(2, 1))
84    );
85}