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}