pcap_parser/
utils.rs

1use std::ops;
2use std::ops::{Deref, DerefMut};
3
4/// A container for owned or borrowed data
5pub enum Data<'a> {
6    Owned(Vec<u8>),
7    Borrowed(&'a [u8]),
8}
9
10/// A container for owned or borrowed mutable data
11pub enum MutableData<'a> {
12    Owned(Vec<u8>),
13    Borrowed(&'a mut [u8]),
14}
15
16impl<'a> Data<'a> {
17    #[inline]
18    pub fn as_slice(&self) -> &[u8] {
19        match self {
20            Data::Owned(ref o) => o.deref(),
21            Data::Borrowed(b) => b,
22        }
23    }
24    #[inline]
25    pub fn len(&self) -> usize {
26        match self {
27            Data::Owned(ref o) => o.len(),
28            Data::Borrowed(b) => b.len(),
29        }
30    }
31    #[inline]
32    pub fn is_empty(&self) -> bool {
33        match self {
34            Data::Owned(ref o) => o.is_empty(),
35            Data::Borrowed(b) => b.is_empty(),
36        }
37    }
38}
39
40impl<'a> MutableData<'a> {
41    #[inline]
42    pub fn as_slice(&self) -> &[u8] {
43        match self {
44            MutableData::Owned(ref o) => o.deref(),
45            MutableData::Borrowed(ref b) => b,
46        }
47    }
48    #[inline]
49    pub fn as_mut_slice(&mut self) -> &mut [u8] {
50        match self {
51            MutableData::Owned(ref mut o) => o.deref_mut(),
52            MutableData::Borrowed(ref mut b) => b,
53        }
54    }
55    #[inline]
56    pub fn len(&self) -> usize {
57        match self {
58            MutableData::Owned(ref o) => o.len(),
59            MutableData::Borrowed(ref b) => b.len(),
60        }
61    }
62    #[inline]
63    pub fn is_empty(&self) -> bool {
64        match self {
65            MutableData::Owned(ref o) => o.is_empty(),
66            MutableData::Borrowed(ref b) => b.is_empty(),
67        }
68    }
69    /// Get an immutable version of the data
70    pub fn into_immutable(self) -> Data<'a> {
71        match self {
72            MutableData::Owned(data) => Data::Owned(data),
73            MutableData::Borrowed(data) => Data::Borrowed(data),
74        }
75    }
76}
77
78/* AsRef */
79
80impl<'a> AsRef<[u8]> for Data<'a> {
81    #[inline]
82    fn as_ref(&self) -> &[u8] {
83        self.as_slice()
84    }
85}
86
87impl<'a> AsRef<[u8]> for MutableData<'a> {
88    #[inline]
89    fn as_ref(&self) -> &[u8] {
90        self.as_slice()
91    }
92}
93
94impl<'a> AsMut<[u8]> for MutableData<'a> {
95    #[inline]
96    fn as_mut(&mut self) -> &mut [u8] {
97        self.as_mut_slice()
98    }
99}
100
101/* Index */
102
103macro_rules! impl_index {
104    ($t:ident, $index_t:ty, $output_t:ty) => {
105        impl<'p> ops::Index<$index_t> for $t<'p> {
106            type Output = $output_t;
107            #[inline]
108            fn index(&self, index: $index_t) -> &$output_t {
109                &self.as_slice().index(index)
110            }
111        }
112    };
113}
114
115macro_rules! impl_index_mut {
116    ($t:ident, $index_t:ty, $output_t:ty) => {
117        impl<'p> ops::IndexMut<$index_t> for $t<'p> {
118            #[inline]
119            fn index_mut(&mut self, index: $index_t) -> &mut $output_t {
120                self.as_mut_slice().index_mut(index)
121            }
122        }
123    };
124}
125
126impl_index!(Data, usize, u8);
127impl_index!(Data, ops::Range<usize>, [u8]);
128impl_index!(Data, ops::RangeTo<usize>, [u8]);
129impl_index!(Data, ops::RangeFrom<usize>, [u8]);
130impl_index!(Data, ops::RangeFull, [u8]);
131impl_index!(Data, ops::RangeInclusive<usize>, [u8]);
132impl_index!(Data, ops::RangeToInclusive<usize>, [u8]);
133
134impl_index!(MutableData, usize, u8);
135impl_index!(MutableData, ops::Range<usize>, [u8]);
136impl_index!(MutableData, ops::RangeTo<usize>, [u8]);
137impl_index!(MutableData, ops::RangeFrom<usize>, [u8]);
138impl_index!(MutableData, ops::RangeFull, [u8]);
139impl_index!(MutableData, ops::RangeInclusive<usize>, [u8]);
140impl_index!(MutableData, ops::RangeToInclusive<usize>, [u8]);
141
142impl_index_mut!(MutableData, usize, u8);
143impl_index_mut!(MutableData, ops::Range<usize>, [u8]);
144impl_index_mut!(MutableData, ops::RangeTo<usize>, [u8]);
145impl_index_mut!(MutableData, ops::RangeFrom<usize>, [u8]);
146impl_index_mut!(MutableData, ops::RangeFull, [u8]);
147impl_index_mut!(MutableData, ops::RangeInclusive<usize>, [u8]);
148impl_index_mut!(MutableData, ops::RangeToInclusive<usize>, [u8]);
149
150/* ******************* */
151
152#[doc(hidden)]
153#[macro_export]
154macro_rules! read_u32_e {
155    ($data:expr, $endian:expr) => {
156        if $endian {
157            let data = $data;
158            (data[0] as u32) << 24
159                | (data[1] as u32) << 16
160                | (data[2] as u32) << 8
161                | (data[3] as u32)
162        } else {
163            let data = $data;
164            (data[3] as u32) << 24
165                | (data[2] as u32) << 16
166                | (data[1] as u32) << 8
167                | (data[0] as u32)
168        }
169    };
170}
171
172#[doc(hidden)]
173#[macro_export]
174macro_rules! write_u32_e {
175    ($data:expr, $val:expr, $endian:expr) => {
176        let data = $data;
177        let v = $val;
178        let v1: u8 = ((v >> 24) & 0xff) as u8;
179        let v2: u8 = ((v >> 16) & 0xff) as u8;
180        let v3: u8 = ((v >> 8) & 0xff) as u8;
181        let v4: u8 = ((v) & 0xff) as u8;
182        if $endian {
183            data[0] = v1;
184            data[1] = v2;
185            data[2] = v3;
186            data[3] = v4;
187        } else {
188            data[0] = v4;
189            data[1] = v3;
190            data[2] = v2;
191            data[3] = v1;
192        }
193    };
194}
195
196/// Generate an array reference to a subset
197/// of a sliceable bit of data (which could be an array, or a slice,
198/// or a Vec).
199///
200/// **Panics** if the slice is out of bounds.
201///
202/// implementation inspired from arrayref::array_ref
203#[allow(unsafe_code)]
204#[inline]
205pub(crate) fn array_ref4(s: &[u8], offset: usize) -> &[u8; 4] {
206    #[inline]
207    unsafe fn as_array<T>(slice: &[T]) -> &[T; 4] {
208        &*(slice.as_ptr() as *const [_; 4])
209    }
210    let slice = &s[offset..offset + 4];
211    #[allow(unused_unsafe)]
212    unsafe {
213        as_array(slice)
214    }
215}