Skip to content

Commit 260e596

Browse files
committed
parser: Use macro to generate integer parser functions
Remove the duplicate code by using macro to generate integer parser functions. Signed-off-by: Gris Ge <fge@redhat.com>
1 parent 41fe03d commit 260e596

File tree

1 file changed

+98
-70
lines changed

1 file changed

+98
-70
lines changed

src/parsers.rs

Lines changed: 98 additions & 70 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ use std::{
55
net::{IpAddr, Ipv4Addr, Ipv6Addr},
66
};
77

8-
use byteorder::{BigEndian, ByteOrder, NativeEndian};
8+
use pastey::paste;
99

1010
use crate::DecodeError;
1111

@@ -88,75 +88,103 @@ pub fn parse_i8(payload: &[u8]) -> Result<i8, DecodeError> {
8888
Ok(payload[0] as i8)
8989
}
9090

91-
pub fn parse_u32(payload: &[u8]) -> Result<u32, DecodeError> {
92-
if payload.len() != size_of::<u32>() {
93-
return Err(DecodeError::invalid_number(
94-
size_of::<u32>(),
95-
payload.len(),
96-
));
91+
macro_rules! gen_int_parser {
92+
( $($data_type:ty,)+ ) => {
93+
$(
94+
95+
paste! {
96+
pub fn [<parse_ $data_type >](
97+
payload: &[u8]
98+
) -> 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_ $data_type _be>](
111+
payload: &[u8]
112+
) -> Result<$data_type, DecodeError> {
113+
if payload.len() != size_of::<$data_type>() {
114+
return Err(DecodeError::invalid_number(
115+
size_of::<$data_type>(),
116+
payload.len(),
117+
));
118+
}
119+
let mut data = [0u8; size_of::<$data_type>()];
120+
data.copy_from_slice(payload);
121+
Ok(<$data_type>::from_be_bytes(data))
122+
}
123+
124+
pub fn [<parse_ $data_type _le>](
125+
payload: &[u8]
126+
) -> Result<$data_type, DecodeError> {
127+
if payload.len() != size_of::<$data_type>() {
128+
return Err(DecodeError::invalid_number(
129+
size_of::<$data_type>(),
130+
payload.len(),
131+
));
132+
}
133+
let mut data = [0u8; size_of::<$data_type>()];
134+
data.copy_from_slice(payload);
135+
Ok(<$data_type>::from_le_bytes(data))
136+
}
137+
138+
pub fn [<emit_ $data_type >](
139+
buf: &mut [u8],
140+
value: $data_type,
141+
) -> Result<(), DecodeError> {
142+
if buf.len() < size_of::<$data_type>() {
143+
return Err(DecodeError::buffer_too_small(
144+
buf.len(),
145+
size_of::<$data_type>(),
146+
));
147+
}
148+
buf[..size_of::<$data_type>()].copy_from_slice(
149+
&value.to_ne_bytes()
150+
);
151+
Ok(())
152+
}
153+
154+
pub fn [<emit_ $data_type _le>](
155+
buf: &mut [u8],
156+
value: $data_type,
157+
) -> Result<(), DecodeError> {
158+
if buf.len() < size_of::<$data_type>() {
159+
return Err(DecodeError::buffer_too_small(
160+
buf.len(),
161+
size_of::<$data_type>(),
162+
));
163+
}
164+
buf[..size_of::<$data_type>()].copy_from_slice(
165+
&value.to_le_bytes()
166+
);
167+
Ok(())
168+
}
169+
170+
pub fn [<emit_ $data_type _be>](
171+
buf: &mut [u8],
172+
value: $data_type,
173+
) -> Result<(), DecodeError> {
174+
if buf.len() < size_of::<$data_type>() {
175+
return Err(DecodeError::buffer_too_small(
176+
buf.len(),
177+
size_of::<$data_type>(),
178+
));
179+
}
180+
buf[..size_of::<$data_type>()].copy_from_slice(
181+
&value.to_be_bytes()
182+
);
183+
Ok(())
184+
}
185+
}
186+
)+
97187
}
98-
Ok(NativeEndian::read_u32(payload))
99188
}
100189

101-
pub fn parse_u64(payload: &[u8]) -> Result<u64, DecodeError> {
102-
if payload.len() != size_of::<u64>() {
103-
return Err(DecodeError::invalid_number(
104-
size_of::<u64>(),
105-
payload.len(),
106-
));
107-
}
108-
Ok(NativeEndian::read_u64(payload))
109-
}
110-
pub fn parse_u128(payload: &[u8]) -> Result<u128, DecodeError> {
111-
if payload.len() != size_of::<u128>() {
112-
return Err(DecodeError::invalid_number(
113-
size_of::<u128>(),
114-
payload.len(),
115-
));
116-
}
117-
Ok(NativeEndian::read_u128(payload))
118-
}
119-
120-
pub fn parse_u16(payload: &[u8]) -> Result<u16, DecodeError> {
121-
if payload.len() != size_of::<u16>() {
122-
return Err(DecodeError::invalid_number(
123-
size_of::<u16>(),
124-
payload.len(),
125-
));
126-
}
127-
Ok(NativeEndian::read_u16(payload))
128-
}
129-
130-
pub fn parse_i32(payload: &[u8]) -> Result<i32, DecodeError> {
131-
if payload.len() != 4 {
132-
return Err(DecodeError::invalid_number(4, payload.len()));
133-
}
134-
Ok(NativeEndian::read_i32(payload))
135-
}
136-
137-
pub fn parse_i64(payload: &[u8]) -> Result<i64, DecodeError> {
138-
if payload.len() != 8 {
139-
return Err(format!("invalid i64: {payload:?}").into());
140-
}
141-
Ok(NativeEndian::read_i64(payload))
142-
}
143-
144-
pub fn parse_u16_be(payload: &[u8]) -> Result<u16, DecodeError> {
145-
if payload.len() != size_of::<u16>() {
146-
return Err(DecodeError::invalid_number(
147-
size_of::<u16>(),
148-
payload.len(),
149-
));
150-
}
151-
Ok(BigEndian::read_u16(payload))
152-
}
153-
154-
pub fn parse_u32_be(payload: &[u8]) -> Result<u32, DecodeError> {
155-
if payload.len() != size_of::<u32>() {
156-
return Err(DecodeError::invalid_number(
157-
size_of::<u32>(),
158-
payload.len(),
159-
));
160-
}
161-
Ok(BigEndian::read_u32(payload))
162-
}
190+
gen_int_parser!(u16, u32, u64, u128, i16, i32, i64, i128,);

0 commit comments

Comments
 (0)