rtps_parser/rtps/messages/submessages/
info_reply.rs

1use crate::rtps::messages::{
2    overall_structure::{
3        RtpsMap, Submessage, SubmessageHeader, SubmessageHeaderRead, SubmessageHeaderWrite,
4    },
5    submessage_elements::{LocatorList, SubmessageElement},
6    types::{SubmessageFlag, SubmessageKind},
7};
8
9#[derive(Debug, PartialEq, Eq)]
10pub struct InfoReplySubmessageRead<'a> {
11    data: &'a [u8],
12}
13
14impl SubmessageHeader for InfoReplySubmessageRead<'_> {
15    fn submessage_header(&self) -> SubmessageHeaderRead {
16        SubmessageHeaderRead::new(self.data)
17    }
18}
19
20impl<'a> InfoReplySubmessageRead<'a> {
21    pub fn new(data: &'a [u8]) -> Self {
22        Self { data }
23    }
24
25    pub fn _multicast_flag(&self) -> bool {
26        self.submessage_header().flags()[1]
27    }
28
29    pub fn _unicast_locator_list(&self) -> LocatorList {
30        self.map(&self.data[4..])
31    }
32
33    pub fn _multicast_locator_list(&self) -> LocatorList {
34        if self._multicast_flag() {
35            let num_locators: u32 = self.map(&self.data[4..]);
36            let octets_to_multicat_loctor_list = num_locators as usize * 24 + 8;
37            self.map(&self.data[octets_to_multicat_loctor_list..])
38        } else {
39            LocatorList::new(vec![])
40        }
41    }
42}
43
44#[derive(Debug, PartialEq, Eq)]
45pub struct InfoReplySubmessageWrite<'a> {
46    multicast_flag: SubmessageFlag,
47    submessage_elements: Vec<SubmessageElement<'a>>,
48}
49
50impl<'a> InfoReplySubmessageWrite<'a> {
51    pub fn _new(
52        multicast_flag: SubmessageFlag,
53        unicast_locator_list: LocatorList,
54        multicast_locator_list: LocatorList,
55    ) -> Self {
56        let mut submessage_elements = vec![SubmessageElement::LocatorList(unicast_locator_list)];
57        if multicast_flag {
58            submessage_elements.push(SubmessageElement::LocatorList(multicast_locator_list));
59        }
60        Self {
61            multicast_flag,
62            submessage_elements,
63        }
64    }
65}
66
67impl<'a> Submessage<'a> for InfoReplySubmessageWrite<'a> {
68    type SubmessageList = &'a [SubmessageElement<'a>];
69
70    fn submessage_header(&self, octets_to_next_header: u16) -> SubmessageHeaderWrite {
71        SubmessageHeaderWrite::new(SubmessageKind::INFO_REPLY, &[], octets_to_next_header)
72    }
73
74    fn submessage_elements(&'a self) -> Self::SubmessageList {
75        &self.submessage_elements
76    }
77}
78
79#[cfg(test)]
80mod tests {
81    use super::*;
82    use crate::rtps::{
83        messages::overall_structure::{into_bytes_vec, RtpsSubmessageWriteKind},
84        types::Locator,
85    };
86
87    #[test]
88    fn serialize_info_reply() {
89        let locator = Locator::new(11, 12, [1; 16]);
90        let submessage = RtpsSubmessageWriteKind::InfoReply(InfoReplySubmessageWrite::_new(
91            false,
92            LocatorList::new(vec![locator]),
93            LocatorList::new(vec![]),
94        ));
95        #[rustfmt::skip]
96        assert_eq!(into_bytes_vec(submessage), vec![
97                0x0f, 0b_0000_0001, 28, 0, // Submessage header
98                1, 0, 0, 0, //numLocators
99                11, 0, 0, 0, //kind
100                12, 0, 0, 0, //port
101                1, 1, 1, 1, //address
102                1, 1, 1, 1, //address
103                1, 1, 1, 1, //address
104                1, 1, 1, 1, //address
105            ]
106        );
107    }
108
109    #[test]
110    fn deserialize_info_reply() {
111        #[rustfmt::skip]
112        let submessage = InfoReplySubmessageRead::new(&[
113            0x0f, 0b_0000_0001, 28, 0, // Submessage header
114            1, 0, 0, 0, //numLocators
115            11, 0, 0, 0, //kind
116            12, 0, 0, 0, //port
117            1, 1, 1, 1, //address
118            1, 1, 1, 1, //address
119            1, 1, 1, 1, //address
120            1, 1, 1, 1, //address
121        ]);
122        let locator = Locator::new(11, 12, [1; 16]);
123        let expected_multicast_flag = false;
124        let expected_unicast_locator_list = LocatorList::new(vec![locator]);
125        let expected_multicast_locator_list = LocatorList::new(vec![]);
126
127        assert_eq!(expected_multicast_flag, submessage._multicast_flag());
128        assert_eq!(
129            expected_unicast_locator_list,
130            submessage._unicast_locator_list()
131        );
132        assert_eq!(
133            expected_multicast_locator_list,
134            submessage._multicast_locator_list()
135        );
136    }
137
138    #[test]
139    fn deserialize_info_reply_with_multicast() {
140        #[rustfmt::skip]
141        let submessage = InfoReplySubmessageRead::new(&[
142            0x0f, 0b_0000_0011, 56, 0, // Submessage header
143            0, 0, 0, 0, //numLocators
144            2, 0, 0, 0, //numLocators
145            11, 0, 0, 0, //kind
146            12, 0, 0, 0, //port
147            1, 1, 1, 1, //address
148            1, 1, 1, 1, //address
149            1, 1, 1, 1, //address
150            1, 1, 1, 1, //address
151            11, 0, 0, 0, //kind
152            12, 0, 0, 0, //port
153            1, 1, 1, 1, //address
154            1, 1, 1, 1, //address
155            1, 1, 1, 1, //address
156            1, 1, 1, 1, //address
157        ]);
158        let locator = Locator::new(11, 12, [1; 16]);
159        let expected_multicast_flag = true;
160        let expected_unicast_locator_list = LocatorList::new(vec![]);
161        let expected_multicast_locator_list = LocatorList::new(vec![locator, locator]);
162
163        assert_eq!(expected_multicast_flag, submessage._multicast_flag());
164        assert_eq!(
165            expected_unicast_locator_list,
166            submessage._unicast_locator_list()
167        );
168        assert_eq!(
169            expected_multicast_locator_list,
170            submessage._multicast_locator_list()
171        );
172    }
173}