1use std::{
4 mem::size_of,
5 net::{IpAddr, Ipv4Addr, Ipv6Addr},
6};
7
8use crate::DecodeError;
9
10pub fn parse_mac(payload: &[u8]) -> Result<[u8; 6], DecodeError> {
11 if payload.len() != 6 {
12 return Err(DecodeError::invalid_mac_address(payload.len()));
13 }
14 let mut address: [u8; 6] = [0; 6];
15 for (i, byte) in payload.iter().enumerate() {
16 address[i] = *byte;
17 }
18 Ok(address)
19}
20
21pub fn parse_ipv6(payload: &[u8]) -> Result<[u8; 16], DecodeError> {
22 if payload.len() != 16 {
23 return Err(DecodeError::invalid_ip_address(payload.len()));
24 }
25 let mut address: [u8; 16] = [0; 16];
26 for (i, byte) in payload.iter().enumerate() {
27 address[i] = *byte;
28 }
29 Ok(address)
30}
31
32pub fn parse_ip(payload: &[u8]) -> Result<IpAddr, DecodeError> {
33 match payload.len() {
34 4 => Ok(
35 Ipv4Addr::new(payload[0], payload[1], payload[2], payload[3])
36 .into(),
37 ),
38 16 => Ok(Ipv6Addr::from([
39 payload[0],
40 payload[1],
41 payload[2],
42 payload[3],
43 payload[4],
44 payload[5],
45 payload[6],
46 payload[7],
47 payload[8],
48 payload[9],
49 payload[10],
50 payload[11],
51 payload[12],
52 payload[13],
53 payload[14],
54 payload[15],
55 ])
56 .into()),
57 other => Err(DecodeError::invalid_ip_address(other)),
58 }
59}
60
61pub fn parse_string(payload: &[u8]) -> Result<String, DecodeError> {
62 if payload.is_empty() {
63 return Ok(String::new());
64 }
65 let slice = if payload[payload.len() - 1] == 0 {
67 &payload[..payload.len() - 1]
68 } else {
69 &payload[..payload.len()]
70 };
71 let s = String::from_utf8(slice.to_vec())?;
72 Ok(s)
73}
74
75pub fn parse_u8(payload: &[u8]) -> Result<u8, DecodeError> {
76 if payload.len() != 1 {
77 return Err(DecodeError::invalid_number(1, payload.len()));
78 }
79 Ok(payload[0])
80}
81
82pub fn parse_i8(payload: &[u8]) -> Result<i8, DecodeError> {
83 if payload.len() != 1 {
84 return Err(DecodeError::invalid_number(1, payload.len()));
85 }
86 Ok(payload[0] as i8)
87}
88
89macro_rules! gen_int_parser {
90 (
91 $(
92 $parse:ident, $parse_be:ident, $parse_le:ident,
93 $emit:ident, $emit_le:ident, $emit_be:ident,
94 $data_type:ty,
95 )+
96 ) => {
97 $(
98 pub fn $parse(payload: &[u8]) -> Result<$data_type, DecodeError> {
99 if payload.len() != size_of::<$data_type>() {
100 return Err(DecodeError::invalid_number(
101 size_of::<$data_type>(),
102 payload.len(),
103 ));
104 }
105 let mut data = [0u8; size_of::<$data_type>()];
106 data.copy_from_slice(payload);
107 Ok(<$data_type>::from_ne_bytes(data))
108 }
109
110 pub fn $parse_be(payload: &[u8]) -> Result<$data_type, DecodeError> {
111 if payload.len() != size_of::<$data_type>() {
112 return Err(DecodeError::invalid_number(
113 size_of::<$data_type>(),
114 payload.len(),
115 ));
116 }
117 let mut data = [0u8; size_of::<$data_type>()];
118 data.copy_from_slice(payload);
119 Ok(<$data_type>::from_be_bytes(data))
120 }
121
122 pub fn $parse_le(payload: &[u8]) -> Result<$data_type, DecodeError> {
123 if payload.len() != size_of::<$data_type>() {
124 return Err(DecodeError::invalid_number(
125 size_of::<$data_type>(),
126 payload.len(),
127 ));
128 }
129 let mut data = [0u8; size_of::<$data_type>()];
130 data.copy_from_slice(payload);
131 Ok(<$data_type>::from_le_bytes(data))
132 }
133
134 pub fn $emit(
135 buf: &mut [u8],
136 value: $data_type,
137 ) -> Result<(), DecodeError> {
138 if buf.len() < size_of::<$data_type>() {
139 return Err(DecodeError::buffer_too_small(
140 buf.len(),
141 size_of::<$data_type>(),
142 ));
143 }
144 buf[..size_of::<$data_type>()]
145 .copy_from_slice(&value.to_ne_bytes());
146 Ok(())
147 }
148
149 pub fn $emit_le(
150 buf: &mut [u8],
151 value: $data_type,
152 ) -> Result<(), DecodeError> {
153 if buf.len() < size_of::<$data_type>() {
154 return Err(DecodeError::buffer_too_small(
155 buf.len(),
156 size_of::<$data_type>(),
157 ));
158 }
159 buf[..size_of::<$data_type>()]
160 .copy_from_slice(&value.to_le_bytes());
161 Ok(())
162 }
163
164 pub fn $emit_be(
165 buf: &mut [u8],
166 value: $data_type,
167 ) -> Result<(), DecodeError> {
168 if buf.len() < size_of::<$data_type>() {
169 return Err(DecodeError::buffer_too_small(
170 buf.len(),
171 size_of::<$data_type>(),
172 ));
173 }
174 buf[..size_of::<$data_type>()]
175 .copy_from_slice(&value.to_be_bytes());
176 Ok(())
177 }
178 )+
179 }
180}
181
182gen_int_parser!(
183 parse_u16,
184 parse_u16_be,
185 parse_u16_le,
186 emit_u16,
187 emit_u16_le,
188 emit_u16_be,
189 u16,
190 parse_u32,
191 parse_u32_be,
192 parse_u32_le,
193 emit_u32,
194 emit_u32_le,
195 emit_u32_be,
196 u32,
197 parse_u64,
198 parse_u64_be,
199 parse_u64_le,
200 emit_u64,
201 emit_u64_le,
202 emit_u64_be,
203 u64,
204 parse_u128,
205 parse_u128_be,
206 parse_u128_le,
207 emit_u128,
208 emit_u128_le,
209 emit_u128_be,
210 u128,
211 parse_i16,
212 parse_i16_be,
213 parse_i16_le,
214 emit_i16,
215 emit_i16_le,
216 emit_i16_be,
217 i16,
218 parse_i32,
219 parse_i32_be,
220 parse_i32_le,
221 emit_i32,
222 emit_i32_le,
223 emit_i32_be,
224 i32,
225 parse_i64,
226 parse_i64_be,
227 parse_i64_le,
228 emit_i64,
229 emit_i64_le,
230 emit_i64_be,
231 i64,
232 parse_i128,
233 parse_i128_be,
234 parse_i128_le,
235 emit_i128,
236 emit_i128_le,
237 emit_i128_be,
238 i128,
239);