1use std::ops;
2use std::ops::{Deref, DerefMut};
3
4pub enum Data<'a> {
6 Owned(Vec<u8>),
7 Borrowed(&'a [u8]),
8}
9
10pub 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 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
78impl<'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
101macro_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#[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#[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}