toe_beans/v4/message/
undecoded.rs

1use crate::v4::MessageBuffer;
2use log::trace;
3
4/// UndecodedMessage takes a message's byte array from the socket. It can return smaller slices that
5/// can be later decoded into a Message's field via `DecodeMessage`.
6///
7/// An advantage to using this over `Slicer` is that this doesn't process input from start to end,
8/// so you may call its methods in any order and as many times as desired without needing to reset.
9pub struct UndecodedMessage(MessageBuffer);
10
11impl<'s> UndecodedMessage {
12    /// `input` must be at least 240 bytes,
13    /// where 240 is the sum of all fixed Message field's bytes
14    /// and the first 4 ("magic") bytes of the variable options field.
15    #[inline]
16    pub fn new(buffer: MessageBuffer) -> Self {
17        Self(buffer)
18    }
19
20    /// Slices 1 byte to be used for the op field
21    #[inline]
22    pub fn slice_op(&self) -> u8 {
23        trace!("slice_op");
24        self.0[0] // PANIC: this won't panic because it is always within the fixed-size array.
25    }
26
27    /// Slices 1 byte to be used for the htype field
28    #[inline]
29    pub fn slice_htype(&self) -> u8 {
30        trace!("slice_htypes");
31        self.0[1] // PANIC: this won't panic because it is always within the fixed-size array.
32    }
33
34    /// Slices 1 byte to be used for the hlen field
35    #[inline]
36    pub fn slice_hlen(&self) -> u8 {
37        trace!("slice_hlen");
38        self.0[2] // PANIC: this won't panic because it is always within the fixed-size array.
39    }
40
41    /// Slices 1 byte to be used for the hops field
42    #[inline]
43    pub fn slice_hops(&self) -> u8 {
44        trace!("slice_hops");
45        self.0[3] // PANIC: this won't panic because it is always within the fixed-size array.
46    }
47
48    /// Slices 4 bytes to be used for the xid field
49    #[inline]
50    pub fn slice_xid(&self) -> [u8; 4] {
51        trace!("slice_xid");
52
53        // PANIC: this won't panic because it is always within the fixed-size array.
54        self.0[4..8].try_into().unwrap()
55    }
56
57    /// Slices 2 bytes to be used for the secs field
58    #[inline]
59    pub fn slice_secs(&self) -> [u8; 2] {
60        trace!("slice_secs");
61
62        // PANIC: this won't panic because it is always within the fixed-size array.
63        self.0[8..10].try_into().unwrap()
64    }
65
66    /// Slices 2 bytes to be used for the flags field
67    #[inline]
68    pub fn slice_flags(&self) -> [u8; 2] {
69        trace!("slice_flags");
70
71        // PANIC: this won't panic because it is always within the fixed-size array.
72        self.0[10..12].try_into().unwrap()
73    }
74
75    /// Slices the only byte currently used by the flags field.
76    ///
77    /// If more bit flags are added via RFC then this may need to
78    /// change or be removed.
79    #[inline]
80    pub fn slice_flags_temporary(&self) -> u8 {
81        trace!("slice_flags_temporary");
82        self.0[10] // PANIC: this won't panic because it is always within the fixed-size array.
83    }
84
85    /// Slices 4 bytes to be used for the ciaddr field
86    #[inline]
87    pub fn slice_ciaddr(&self) -> [u8; 4] {
88        trace!("slice_ciaddr");
89
90        // PANIC: this won't panic because it is always within the fixed-size array.
91        self.0[12..16].try_into().unwrap()
92    }
93
94    /// Slices 4 bytes to be used for the yiaddr field
95    #[inline]
96    pub fn slice_yiaddr(&self) -> [u8; 4] {
97        trace!("slice_yiaddr");
98
99        // PANIC: this won't panic because it is always within the fixed-size array.
100        self.0[16..20].try_into().unwrap()
101    }
102
103    /// Slices 4 bytes to be used for the siaddr field
104    #[inline]
105    pub fn slice_siaddr(&self) -> [u8; 4] {
106        trace!("slice_siaddr");
107
108        // PANIC: this won't panic because it is always within the fixed-size array.
109        self.0[20..24].try_into().unwrap()
110    }
111
112    /// Slices 4 bytes to be used for the giaddr field
113    #[inline]
114    pub fn slice_giaddr(&self) -> [u8; 4] {
115        trace!("slice_giaddr");
116
117        // PANIC: this won't panic because it is always within the fixed-size array.
118        self.0[24..28].try_into().unwrap()
119    }
120
121    /// Slices 16 bytes to be used for the chaddr field
122    #[inline]
123    pub fn slice_chaddr(&self) -> [u8; 16] {
124        trace!("slice_chaddr");
125
126        // PANIC: this won't panic because it is always within the fixed-size array.
127        self.0[28..44].try_into().unwrap()
128    }
129
130    /// Slices 64 bytes to be used for the sname field
131    #[inline]
132    pub fn slice_sname(&self) -> [u8; 64] {
133        trace!("slice_sname");
134
135        // PANIC: this won't panic because it is always within the fixed-size array.
136        self.0[44..108].try_into().unwrap()
137    }
138
139    /// Slices 128 bytes to be used for the file field
140    #[inline]
141    pub fn slice_file(&self) -> [u8; 128] {
142        trace!("slice_file");
143
144        // PANIC: this won't panic because it is always within the fixed-size array.
145        self.0[108..236].try_into().unwrap()
146    }
147
148    /// Slices 4 bytes to be used as the magic field
149    #[inline]
150    pub fn slice_magic(&self) -> [u8; 4] {
151        trace!("slice_magic");
152
153        // PANIC: this won't panic because it is always within the fixed-size array.
154        self.0[236..240].try_into().unwrap()
155    }
156
157    /// Slices all remaining bytes in the input to be used as the options field
158    #[inline]
159    pub fn slice_options(&'s self) -> &'s [u8] {
160        trace!("slice_options");
161
162        // PANIC: this won't panic because it is always within the fixed-size array.
163        &self.0[240..]
164    }
165}