toe_beans/v4/message/slicer.rs
1use log::trace;
2
3/// Takes a slice as input and divides it into smaller slices.
4/// This processes the slice from start to end by user-provided _len_ sized chunks.
5///
6/// For example `&[1, 2, 3, 4] --> &[1, 2] and &[3, 4]`.
7///
8/// Uses:
9/// - When you know the length to slice at runtime but not compile time.
10/// - When parsing formats within formats. For example,
11/// the DHCP format has an options field that contains TLV
12/// formatted options. See `options/options.rs`.
13#[derive(Debug)]
14pub struct Slicer<'de> {
15 input: &'de [u8],
16 input_index: usize,
17}
18
19impl<'de> Slicer<'de> {
20 /// Creates an instance of Slicer.
21 pub fn new(input: &'de [u8]) -> Self {
22 Slicer {
23 input,
24 input_index: 0,
25 }
26 }
27
28 /// Returns the next len number of bytes and changes the current position the same amount.
29 ///
30 /// Returns an Option instead of panicking. Use `slice_unchecked` if it is okay to panic.
31 #[inline]
32 pub fn slice(&mut self, len: usize) -> Option<&'de [u8]> {
33 trace!("slice");
34 let slice = self.input.get(self.input_index..self.input_index + len);
35
36 if slice.is_some() {
37 self.input_index += len;
38 }
39
40 slice
41 }
42
43 /// Returns the next len number of bytes and changes the current position the same amount.
44 ///
45 /// Can panic if slicing past array length. Use `slice` for no panic.
46 #[inline]
47 pub fn slice_unchecked(&mut self, len: usize) -> &'de [u8] {
48 trace!("slice_unchecked");
49 let slice = &self.input[self.input_index..self.input_index + len];
50 self.input_index += len;
51 slice
52 }
53
54 /// Returns the remaining bytes in the input and resets the current position to the start.
55 #[inline]
56 pub fn slice_remainder(&mut self) -> &'de [u8] {
57 trace!("slice_remainder");
58 let slice = &self.input[self.input_index..];
59 self.reset();
60 slice
61 }
62
63 /// Slicer keeps track of how many bytes have been sliced (the position from start).
64 /// This resets that internal state.
65 #[inline]
66 pub fn reset(&mut self) {
67 self.input_index = 0;
68 }
69}