Skip to content

Commit c658ace

Browse files
committed
Refactor parsing to use slice::chunks_exact
This avoids doing manual offset handling and for loops, and instead iterates on a chunked view of the data, which is easier to maintain.
1 parent c19bf61 commit c658ace

File tree

5 files changed

+34
-40
lines changed

5 files changed

+34
-40
lines changed

src/packet/forward_tsn_chunk.rs

Lines changed: 8 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -62,16 +62,15 @@ impl TryFrom<RawChunk<'_>> for ForwardTsnChunk {
6262
ensure!(raw.value.len() >= 4 && (raw.value.len() % 4) == 0, ChunkParseError::InvalidLength);
6363

6464
let new_cumulative_tsn = Tsn(read_u32_be!(&raw.value[0..4]));
65-
let num_skipped = (raw.value.len() - 4) / 4;
6665

67-
let mut skipped_streams = Vec::<SkippedStream>::with_capacity(num_skipped);
68-
let mut offset = 4;
69-
for _ in 0..num_skipped {
70-
let stream_id = StreamId(read_u16_be!(&raw.value[offset..offset + 2]));
71-
let ssn = Ssn(read_u16_be!(&raw.value[offset + 2..offset + 4]));
72-
skipped_streams.push(SkippedStream::ForwardTsn(stream_id, ssn));
73-
offset += 4;
74-
}
66+
let skipped_streams = raw.value[4..]
67+
.chunks_exact(4)
68+
.map(|c| {
69+
let stream_id = StreamId(read_u16_be!(&c[0..2]));
70+
let ssn = Ssn(read_u16_be!(&c[2..4]));
71+
SkippedStream::ForwardTsn(stream_id, ssn)
72+
})
73+
.collect();
7574

7675
Ok(Self { new_cumulative_tsn, skipped_streams })
7776
}

src/packet/iforward_tsn_chunk.rs

Lines changed: 9 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -70,18 +70,16 @@ impl TryFrom<RawChunk<'_>> for IForwardTsnChunk {
7070
);
7171

7272
let new_cumulative_tsn = Tsn(read_u32_be!(&raw.value[0..4]));
73-
let num_skipped = (raw.value.len() - 4) / 8;
7473

75-
let mut skipped_streams = Vec::<SkippedStream>::with_capacity(num_skipped);
76-
let mut offset = 4;
77-
for _ in 0..num_skipped {
78-
let stream_id = StreamId(read_u16_be!(&raw.value[offset..offset + 2]));
79-
let is_unordered = (raw.value[offset + 3] & 1) != 0;
80-
let mid = Mid(read_u32_be!(&raw.value[offset + 4..offset + 8]));
81-
skipped_streams
82-
.push(SkippedStream::IForwardTsn(StreamKey::from(is_unordered, stream_id), mid));
83-
offset += 8;
84-
}
74+
let skipped_streams = raw.value[4..]
75+
.chunks_exact(8)
76+
.map(|c| {
77+
let stream_id = StreamId(read_u16_be!(&c[0..2]));
78+
let is_unordered = (c[3] & 1) != 0;
79+
let mid = Mid(read_u32_be!(&c[4..8]));
80+
SkippedStream::IForwardTsn(StreamKey::from(is_unordered, stream_id), mid)
81+
})
82+
.collect();
8583

8684
Ok(Self { new_cumulative_tsn, skipped_streams })
8785
}

src/packet/incoming_ssn_reset_request_parameter.rs

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -58,9 +58,7 @@ impl TryFrom<RawParameter<'_>> for IncomingSsnResetRequestParameter {
5858
ensure!(raw.value.len() >= 4 && (raw.value.len() % 2) == 0, ChunkParseError::InvalidLength);
5959

6060
let request_seq_nbr = read_u32_be!(&raw.value[0..4]);
61-
let streams = (0..(raw.value.len() - 4) / 2)
62-
.map(|i| StreamId(read_u16_be!(&raw.value[4 + i * 2..4 + i * 2 + 2])))
63-
.collect();
61+
let streams = raw.value[4..].chunks_exact(2).map(|c| StreamId(read_u16_be!(c))).collect();
6462

6563
Ok(Self { request_seq_nbr, streams })
6664
}

src/packet/outgoing_ssn_reset_request_parameter.rs

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -67,9 +67,7 @@ impl TryFrom<RawParameter<'_>> for OutgoingSsnResetRequestParameter {
6767
ChunkParseError::InvalidLength
6868
);
6969

70-
let streams = (0..(raw.value.len() - 12) / 2)
71-
.map(|i| StreamId(read_u16_be!(&raw.value[12 + i * 2..12 + i * 2 + 2])))
72-
.collect();
70+
let streams = raw.value[12..].chunks_exact(2).map(|c| StreamId(read_u16_be!(c))).collect();
7371

7472
Ok(Self {
7573
request_seq_nbr: read_u32_be!(&raw.value[0..4]),

src/packet/sack_chunk.rs

Lines changed: 15 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -95,20 +95,21 @@ impl TryFrom<RawChunk<'_>> for SackChunk {
9595
ChunkParseError::InvalidLength
9696
);
9797

98-
let mut gap_ack_blocks = Vec::<GapAckBlock>::with_capacity(nbr_of_gap_blocks);
99-
let mut offset = 12;
100-
for _ in 0..nbr_of_gap_blocks {
101-
let start = read_u16_be!(&raw.value[offset..offset + 2]);
102-
let end = read_u16_be!(&raw.value[offset + 2..offset + 4]);
103-
gap_ack_blocks.push(GapAckBlock { start, end });
104-
offset += 4;
105-
}
106-
107-
let mut duplicate_tsns = Vec::<Tsn>::with_capacity(nbr_of_dup_tsns);
108-
for _ in 0..nbr_of_dup_tsns {
109-
duplicate_tsns.push(Tsn(read_u32_be!(&raw.value[offset..offset + 4])));
110-
offset += 4;
111-
}
98+
let gap_blocks_end = 12 + nbr_of_gap_blocks * 4;
99+
let gap_ack_blocks_data = &raw.value[12..gap_blocks_end];
100+
let duplicate_tsns_data = &raw.value[gap_blocks_end..];
101+
102+
let gap_ack_blocks = gap_ack_blocks_data
103+
.chunks_exact(4)
104+
.map(|c| {
105+
let start = read_u16_be!(&c[0..2]);
106+
let end = read_u16_be!(&c[2..4]);
107+
GapAckBlock { start, end }
108+
})
109+
.collect();
110+
111+
let duplicate_tsns =
112+
duplicate_tsns_data.chunks_exact(4).map(|c| Tsn(read_u32_be!(c))).collect();
112113

113114
Ok(Self { cumulative_tsn_ack, a_rwnd, gap_ack_blocks, duplicate_tsns })
114115
}

0 commit comments

Comments
 (0)