rtps_parser/rtps/messages/submessages/
gap.rs

1use crate::rtps::{
2    messages::{
3        overall_structure::{
4            RtpsMap, Submessage, SubmessageHeader, SubmessageHeaderRead, SubmessageHeaderWrite,
5        },
6        submessage_elements::{SequenceNumberSet, SubmessageElement},
7        types::SubmessageKind,
8    },
9    types::{EntityId, SequenceNumber},
10};
11
12#[derive(Debug, PartialEq, Eq)]
13pub struct GapSubmessageRead<'a> {
14    data: &'a [u8],
15}
16
17impl SubmessageHeader for GapSubmessageRead<'_> {
18    fn submessage_header(&self) -> SubmessageHeaderRead {
19        SubmessageHeaderRead::new(self.data)
20    }
21}
22
23impl<'a> GapSubmessageRead<'a> {
24    pub fn new(data: &'a [u8]) -> Self {
25        Self { data }
26    }
27
28    pub fn _reader_id(&self) -> EntityId {
29        self.map(&self.data[4..])
30    }
31
32    pub fn writer_id(&self) -> EntityId {
33        self.map(&self.data[8..])
34    }
35
36    pub fn gap_start(&self) -> SequenceNumber {
37        self.map(&self.data[12..])
38    }
39
40    pub fn gap_list(&self) -> SequenceNumberSet {
41        self.map(&self.data[20..])
42    }
43}
44
45#[derive(Debug, PartialEq, Eq)]
46pub struct GapSubmessageWrite<'a> {
47    submessage_elements: [SubmessageElement<'a>; 4],
48}
49
50impl GapSubmessageWrite<'_> {
51    pub fn new(
52        reader_id: EntityId,
53        writer_id: EntityId,
54        gap_start: SequenceNumber,
55        gap_list: SequenceNumberSet,
56    ) -> Self {
57        Self {
58            submessage_elements: [
59                SubmessageElement::EntityId(reader_id),
60                SubmessageElement::EntityId(writer_id),
61                SubmessageElement::SequenceNumber(gap_start),
62                SubmessageElement::SequenceNumberSet(gap_list),
63            ],
64        }
65    }
66}
67
68impl<'a> Submessage<'a> for GapSubmessageWrite<'a> {
69    type SubmessageList = &'a [SubmessageElement<'a>];
70
71    fn submessage_header(&self, octets_to_next_header: u16) -> SubmessageHeaderWrite {
72        SubmessageHeaderWrite::new(SubmessageKind::GAP, &[], octets_to_next_header)
73    }
74
75    fn submessage_elements(&'a self) -> Self::SubmessageList {
76        &self.submessage_elements
77    }
78}
79
80#[cfg(test)]
81mod tests {
82    use crate::rtps::{
83        messages::overall_structure::{into_bytes_vec, RtpsSubmessageWriteKind},
84        types::{USER_DEFINED_READER_GROUP, USER_DEFINED_READER_NO_KEY},
85    };
86
87    #[test]
88    fn serialize_gap() {
89        let reader_id = EntityId::new([1, 2, 3], USER_DEFINED_READER_NO_KEY);
90        let writer_id = EntityId::new([6, 7, 8], USER_DEFINED_READER_GROUP);
91        let gap_start = SequenceNumber::from(5);
92        let gap_list = SequenceNumberSet::new(SequenceNumber::from(10), []);
93        let submessage = RtpsSubmessageWriteKind::Gap(GapSubmessageWrite::new(
94            reader_id, writer_id, gap_start, gap_list,
95        ));
96        #[rustfmt::skip]
97        assert_eq!(into_bytes_vec(submessage), vec![
98                0x08_u8, 0b_0000_0001, 28, 0, // Submessage header
99                1, 2, 3, 4, // readerId: value[4]
100                6, 7, 8, 9, // writerId: value[4]
101                0, 0, 0, 0, // gapStart: SequenceNumber: high
102                5, 0, 0, 0, // gapStart: SequenceNumber: low
103                0, 0, 0, 0, // gapList: SequenceNumberSet: bitmapBase: high
104               10, 0, 0, 0, // gapList: SequenceNumberSet: bitmapBase: low
105                0, 0, 0, 0, // gapList: SequenceNumberSet: numBits (ULong)
106            ]
107        );
108    }
109
110    use super::*;
111    #[test]
112    fn deserialize_gap() {
113        let expected_reader_id = EntityId::new([1, 2, 3], USER_DEFINED_READER_NO_KEY);
114        let expected_writer_id = EntityId::new([6, 7, 8], USER_DEFINED_READER_GROUP);
115        let expected_gap_start = SequenceNumber::from(5);
116        let expected_gap_list = SequenceNumberSet::new(SequenceNumber::from(10), []);
117        #[rustfmt::skip]
118        let submessage = GapSubmessageRead::new(&[
119            0x08, 0b_0000_0001, 28, 0, // Submessage header
120            1, 2, 3, 4, // readerId: value[4]
121            6, 7, 8, 9, // writerId: value[4]
122            0, 0, 0, 0, // gapStart: SequenceNumber: high
123            5, 0, 0, 0, // gapStart: SequenceNumber: low
124            0, 0, 0, 0, // gapList: SequenceNumberSet: bitmapBase: high
125           10, 0, 0, 0, // gapList: SequenceNumberSet: bitmapBase: low
126            0, 0, 0, 0, // gapList: SequenceNumberSet: numBits (ULong)
127        ]);
128        assert_eq!(expected_reader_id, submessage._reader_id());
129        assert_eq!(expected_writer_id, submessage.writer_id());
130        assert_eq!(expected_gap_start, submessage.gap_start());
131        assert_eq!(expected_gap_list, submessage.gap_list());
132    }
133}