Skip to main content

leodos_protocols/datalink/spp/segmentation/
segmenter.rs

1use crate::network::spp::SequenceCount;
2use crate::network::spp::SequenceFlag;
3
4/// An iterator that breaks a large data slice into chunks suitable for
5/// creating a sequence of segmented `SpacePacket`s.
6pub struct Segmenter<'a> {
7    data: &'a [u8],
8    segment_size: usize,
9    sequence_count: SequenceCount,
10    position: usize,
11    is_first: bool,
12}
13
14/// Contains the necessary data to construct one `SpacePacket` in a segmented sequence.
15#[derive(Debug, PartialEq, Eq)]
16pub struct SegmentedPacketData<'a> {
17    /// Whether this is the first, continuation, or last segment.
18    pub sequence_flag: SequenceFlag,
19    /// The sequence count for this segment's packet.
20    pub sequence_count: SequenceCount,
21    /// The data slice for this segment.
22    pub payload: &'a [u8],
23}
24
25impl<'a> Segmenter<'a> {
26    /// Creates a new `Segmenter` iterator.
27    pub fn new(data: &'a [u8], segment_size: usize, start_count: SequenceCount) -> Self {
28        Self {
29            data,
30            segment_size,
31            sequence_count: start_count,
32            position: 0,
33            is_first: true,
34        }
35    }
36}
37
38impl<'a> Iterator for Segmenter<'a> {
39    type Item = SegmentedPacketData<'a>;
40
41    fn next(&mut self) -> Option<Self::Item> {
42        if self.position >= self.data.len() {
43            return None;
44        }
45
46        let sequence_flag = if self.is_first {
47            self.is_first = false;
48            SequenceFlag::First
49        } else if self.position + self.segment_size >= self.data.len() {
50            SequenceFlag::Last
51        } else {
52            SequenceFlag::Continuation
53        };
54
55        let end = (self.position + self.segment_size).min(self.data.len());
56        let payload = &self.data[self.position..end];
57        self.position = end;
58
59        let item = SegmentedPacketData {
60            sequence_flag,
61            sequence_count: self.sequence_count,
62            payload,
63        };
64
65        self.sequence_count.increment();
66        Some(item)
67    }
68}