Skip to content

Commit 7f142c4

Browse files
committed
macros: Add macros from netlink-core-utils
Signed-off-by: Enrique Llorente <[email protected]>
1 parent 8be2fe8 commit 7f142c4

File tree

2 files changed

+241
-0
lines changed

2 files changed

+241
-0
lines changed

src/lib.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -273,3 +273,6 @@ pub use self::nla::*;
273273

274274
pub mod parsers;
275275
pub use self::parsers::*;
276+
277+
#[macro_use]
278+
mod macros;

src/macros.rs

Lines changed: 238 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,238 @@
1+
// SPDX-License-Identifier: MIT
2+
3+
#[macro_export(local_inner_macros)]
4+
macro_rules! getter {
5+
($buffer: ident, $name:ident, slice, $offset:expr) => {
6+
impl<'a, T: AsRef<[u8]> + ?Sized> $buffer<&'a T> {
7+
pub fn $name(&self) -> &'a [u8] {
8+
&self.buffer.as_ref()[$offset]
9+
}
10+
}
11+
};
12+
($buffer: ident, $name:ident, $ty:tt, $offset:expr) => {
13+
impl<'a, T: AsRef<[u8]>> $buffer<T> {
14+
getter!($name, $ty, $offset);
15+
}
16+
};
17+
($name:ident, u8, $offset:expr) => {
18+
pub fn $name(&self) -> u8 {
19+
self.buffer.as_ref()[$offset]
20+
}
21+
};
22+
($name:ident, u16, $offset:expr) => {
23+
pub fn $name(&self) -> u16 {
24+
use $crate::byteorder::{ByteOrder, NativeEndian};
25+
NativeEndian::read_u16(&self.buffer.as_ref()[$offset])
26+
}
27+
};
28+
($name:ident, u32, $offset:expr) => {
29+
pub fn $name(&self) -> u32 {
30+
use $crate::byteorder::{ByteOrder, NativeEndian};
31+
NativeEndian::read_u32(&self.buffer.as_ref()[$offset])
32+
}
33+
};
34+
($name:ident, u64, $offset:expr) => {
35+
pub fn $name(&self) -> u64 {
36+
use $crate::byteorder::{ByteOrder, NativeEndian};
37+
NativeEndian::read_u64(&self.buffer.as_ref()[$offset])
38+
}
39+
};
40+
($name:ident, i8, $offset:expr) => {
41+
pub fn $name(&self) -> i8 {
42+
self.buffer.as_ref()[$offset]
43+
}
44+
};
45+
($name:ident, i16, $offset:expr) => {
46+
pub fn $name(&self) -> i16 {
47+
use $crate::byteorder::{ByteOrder, NativeEndian};
48+
NativeEndian::read_i16(&self.buffer.as_ref()[$offset])
49+
}
50+
};
51+
($name:ident, i32, $offset:expr) => {
52+
pub fn $name(&self) -> i32 {
53+
use $crate::byteorder::{ByteOrder, NativeEndian};
54+
NativeEndian::read_i32(&self.buffer.as_ref()[$offset])
55+
}
56+
};
57+
($name:ident, i64, $offset:expr) => {
58+
pub fn $name(&self) -> i64 {
59+
use $crate::byteorder::{ByteOrder, NativeEndian};
60+
NativeEndian::read_i64(&self.buffer.as_ref()[$offset])
61+
}
62+
};
63+
}
64+
65+
#[macro_export(local_inner_macros)]
66+
macro_rules! setter {
67+
($buffer: ident, $name:ident, slice, $offset:expr) => {
68+
impl<'a, T: AsRef<[u8]> + AsMut<[u8]> + ?Sized> $buffer<&'a mut T> {
69+
$crate::pastey::item! {
70+
pub fn [<$name _mut>](&mut self) -> &mut [u8] {
71+
&mut self.buffer.as_mut()[$offset]
72+
}
73+
}
74+
}
75+
};
76+
($buffer: ident, $name:ident, $ty:tt, $offset:expr) => {
77+
impl<'a, T: AsRef<[u8]> + AsMut<[u8]>> $buffer<T> {
78+
setter!($name, $ty, $offset);
79+
}
80+
};
81+
($name:ident, u8, $offset:expr) => {
82+
$crate::pastey::item! {
83+
pub fn [<set_ $name>](&mut self, value: u8) {
84+
self.buffer.as_mut()[$offset] = value;
85+
}
86+
}
87+
};
88+
($name:ident, u16, $offset:expr) => {
89+
$crate::pastey::item! {
90+
pub fn [<set_ $name>](&mut self, value: u16) {
91+
use $crate::byteorder::{ByteOrder, NativeEndian};
92+
NativeEndian::write_u16(&mut self.buffer.as_mut()[$offset], value)
93+
}
94+
}
95+
};
96+
($name:ident, u32, $offset:expr) => {
97+
$crate::pastey::item! {
98+
pub fn [<set_ $name>](&mut self, value: u32) {
99+
use $crate::byteorder::{ByteOrder, NativeEndian};
100+
NativeEndian::write_u32(&mut self.buffer.as_mut()[$offset], value)
101+
}
102+
}
103+
};
104+
($name:ident, u64, $offset:expr) => {
105+
$crate::pastey::item! {
106+
pub fn [<set_ $name>](&mut self, value: u64) {
107+
use $crate::byteorder::{ByteOrder, NativeEndian};
108+
NativeEndian::write_u64(&mut self.buffer.as_mut()[$offset], value)
109+
}
110+
}
111+
};
112+
($name:ident, i8, $offset:expr) => {
113+
$crate::pastey::item! {
114+
pub fn [<set_ $name>](&mut self, value: i8) {
115+
self.buffer.as_mut()[$offset] = value;
116+
}
117+
}
118+
};
119+
($name:ident, i16, $offset:expr) => {
120+
$crate::pastey::item! {
121+
pub fn [<set_ $name>](&mut self, value: i16) {
122+
use $crate::byteorder::{ByteOrder, NativeEndian};
123+
NativeEndian::write_i16(&mut self.buffer.as_mut()[$offset], value)
124+
}
125+
}
126+
};
127+
($name:ident, i32, $offset:expr) => {
128+
$crate::pastey::item! {
129+
pub fn [<set_ $name>](&mut self, value: i32) {
130+
use $crate::byteorder::{ByteOrder, NativeEndian};
131+
NativeEndian::write_i32(&mut self.buffer.as_mut()[$offset], value)
132+
}
133+
}
134+
};
135+
($name:ident, i64, $offset:expr) => {
136+
$crate::pastey::item! {
137+
pub fn [<set_ $name>](&mut self, value: i64) {
138+
use $crate::byteorder::{ByteOrder, NativeEndian};
139+
NativeEndian::write_i64(&mut self.buffer.as_mut()[$offset], value)
140+
}
141+
}
142+
};
143+
}
144+
145+
#[macro_export(local_inner_macros)]
146+
macro_rules! buffer {
147+
($name:ident($buffer_len:expr) { $($field:ident : ($ty:tt, $offset:expr)),* $(,)? }) => {
148+
buffer!($name { $($field: ($ty, $offset),)* });
149+
buffer_check_length!($name($buffer_len));
150+
};
151+
152+
($name:ident { $($field:ident : ($ty:tt, $offset:expr)),* $(,)? }) => {
153+
buffer_common!($name);
154+
fields!($name {
155+
$($field: ($ty, $offset),)*
156+
});
157+
};
158+
159+
($name:ident, $buffer_len:expr) => {
160+
buffer_common!($name);
161+
buffer_check_length!($name($buffer_len));
162+
};
163+
164+
($name:ident) => {
165+
buffer_common!($name);
166+
};
167+
}
168+
169+
#[macro_export(local_inner_macros)]
170+
macro_rules! fields {
171+
($buffer:ident { $($name:ident : ($ty:tt, $offset:expr)),* $(,)? }) => {
172+
$(
173+
getter!($buffer, $name, $ty, $offset);
174+
)*
175+
176+
$(
177+
setter!($buffer, $name, $ty, $offset);
178+
)*
179+
}
180+
}
181+
182+
#[macro_export]
183+
macro_rules! buffer_check_length {
184+
($name:ident($buffer_len:expr)) => {
185+
impl<T: AsRef<[u8]>> $name<T> {
186+
pub fn new_checked(buffer: T) -> Result<Self, DecodeError> {
187+
let packet = Self::new(buffer);
188+
packet.check_buffer_length()?;
189+
Ok(packet)
190+
}
191+
192+
fn check_buffer_length(&self) -> Result<(), DecodeError> {
193+
let len = self.buffer.as_ref().len();
194+
if len < $buffer_len {
195+
Err(DecodeError::InvalidBuffer {
196+
name: stringify!($name),
197+
received: len,
198+
minimum_length: $buffer_len,
199+
})
200+
} else {
201+
Ok(())
202+
}
203+
}
204+
}
205+
};
206+
}
207+
208+
#[macro_export]
209+
macro_rules! buffer_common {
210+
($name:ident) => {
211+
#[derive(Debug, PartialEq, Eq, Clone, Copy)]
212+
pub struct $name<T> {
213+
buffer: T,
214+
}
215+
216+
impl<T: AsRef<[u8]>> $name<T> {
217+
pub fn new(buffer: T) -> Self {
218+
Self { buffer }
219+
}
220+
221+
pub fn into_inner(self) -> T {
222+
self.buffer
223+
}
224+
}
225+
226+
impl<'a, T: AsRef<[u8]> + ?Sized> $name<&'a T> {
227+
pub fn inner(&self) -> &'a [u8] {
228+
&self.buffer.as_ref()[..]
229+
}
230+
}
231+
232+
impl<'a, T: AsRef<[u8]> + AsMut<[u8]> + ?Sized> $name<&'a mut T> {
233+
pub fn inner_mut(&mut self) -> &mut [u8] {
234+
&mut self.buffer.as_mut()[..]
235+
}
236+
}
237+
};
238+
}

0 commit comments

Comments
 (0)