1use crate::utils::HexValue;
2use byteorder::{ByteOrder, NativeEndian};
3use std::borrow::Cow;
4use std::cmp::min;
5use std::ops::Range;
6use std::{fmt, mem};
7
8#[derive(Clone, Copy, PartialEq, Eq)]
16pub enum RawData<'a> {
17 Single(&'a [u8]),
18 Split(&'a [u8], &'a [u8]),
19}
20
21impl<'a> From<&'a Cow<'a, [u8]>> for RawData<'a> {
22 fn from(data: &'a Cow<'a, [u8]>) -> Self {
23 match *data {
24 Cow::Owned(ref bytes) => RawData::Single(bytes.as_slice()),
25 Cow::Borrowed(bytes) => RawData::Single(bytes),
26 }
27 }
28}
29
30impl<'a> From<&'a [u8]> for RawData<'a> {
31 fn from(bytes: &'a [u8]) -> Self {
32 RawData::Single(bytes)
33 }
34}
35
36struct DisplayableSlice<'a>(&'a [u8]);
38
39impl fmt::Display for DisplayableSlice<'_> {
40 fn fmt(&self, fmt: &mut fmt::Formatter) -> Result<(), fmt::Error> {
41 let len = self.0.len();
42 if len == 0 {
43 return fmt.write_str("[]");
44 }
45
46 const MAX_PRINT_COUNT: usize = 20;
47 let need_ellipsis = len > MAX_PRINT_COUNT;
48 let print_count = len.min(MAX_PRINT_COUNT);
49 let last_printed_index = print_count - 1;
50
51 fmt.write_str("[")?;
52 for b in self.0.iter().take(last_printed_index) {
53 write!(fmt, "{b}, ")?;
54 }
55 write!(fmt, "{}", self.0[last_printed_index])?;
56 if need_ellipsis {
57 write!(
58 fmt,
59 ", ... (and {} more, total length {})",
60 len - MAX_PRINT_COUNT,
61 len
62 )?;
63 }
64 fmt.write_str("]")?;
65 Ok(())
66 }
67}
68
69impl fmt::Debug for RawData<'_> {
70 fn fmt(&self, fmt: &mut fmt::Formatter) -> Result<(), fmt::Error> {
71 match *self {
72 RawData::Single(buffer) => {
73 write!(fmt, "RawData::Single({})", &DisplayableSlice(buffer))
74 }
75 RawData::Split(left, right) => write!(
76 fmt,
77 "RawData::Split({}, {})",
78 &DisplayableSlice(left),
79 &DisplayableSlice(right),
80 ),
81 }
82 }
83}
84
85impl<'a> RawData<'a> {
86 #[inline]
87 pub fn empty() -> Self {
88 RawData::Single(&[])
89 }
90
91 pub fn read_exact(&mut self, buf: &mut [u8]) -> Result<(), std::io::Error> {
92 let buf_len = buf.len();
93 *self = match *self {
94 RawData::Single(single) => {
95 if single.len() < buf_len {
96 return Err(std::io::ErrorKind::UnexpectedEof.into());
97 }
98 buf.copy_from_slice(&single[..buf_len]);
99 RawData::Single(&single[buf_len..])
100 }
101 RawData::Split(left, right) => {
102 let left_len = left.len();
103 if buf_len <= left_len {
104 buf.copy_from_slice(&left[..buf_len]);
105 if buf_len < left_len {
106 RawData::Split(&left[buf_len..], right)
107 } else {
108 RawData::Single(right)
109 }
110 } else {
111 let remainder_len = buf_len - left_len;
112 if remainder_len > right.len() {
113 return Err(std::io::ErrorKind::UnexpectedEof.into());
114 }
115 buf[..left_len].copy_from_slice(left);
116 buf[left_len..].copy_from_slice(&right[..remainder_len]);
117 RawData::Single(&right[remainder_len..])
118 }
119 }
120 };
121 Ok(())
122 }
123
124 pub fn read_u64<T: ByteOrder>(&mut self) -> Result<u64, std::io::Error> {
125 let mut b = [0; 8];
126 self.read_exact(&mut b)?;
127 Ok(T::read_u64(&b))
128 }
129
130 pub fn read_u32<T: ByteOrder>(&mut self) -> Result<u32, std::io::Error> {
131 let mut b = [0; 4];
132 self.read_exact(&mut b)?;
133 Ok(T::read_u32(&b))
134 }
135
136 pub fn read_i32<T: ByteOrder>(&mut self) -> Result<i32, std::io::Error> {
137 let mut b = [0; 4];
138 self.read_exact(&mut b)?;
139 Ok(T::read_i32(&b))
140 }
141
142 pub fn read_u16<T: ByteOrder>(&mut self) -> Result<u16, std::io::Error> {
143 let mut b = [0; 2];
144 self.read_exact(&mut b)?;
145 Ok(T::read_u16(&b))
146 }
147
148 pub fn read_u8(&mut self) -> Result<u8, std::io::Error> {
149 let mut b = [0; 1];
150 self.read_exact(&mut b)?;
151 Ok(b[0])
152 }
153
154 pub fn read_string(&mut self) -> Option<RawData<'a>> {
157 let (rv, new_self) = match *self {
158 RawData::Single(single) => {
159 let n = memchr::memchr(0, single)?;
160 (
161 RawData::Single(&single[..n]),
162 RawData::Single(&single[n + 1..]),
163 )
164 }
165 RawData::Split(left, right) => {
166 if let Some(n) = memchr::memchr(0, left) {
167 (
168 RawData::Single(&left[..n]),
169 if n + 1 < left.len() {
170 RawData::Split(&left[n + 1..], right)
171 } else {
172 RawData::Single(right)
173 },
174 )
175 } else if let Some(n) = memchr::memchr(0, right) {
176 (
177 RawData::Split(left, &right[..n]),
178 RawData::Single(&right[n + 1..]),
179 )
180 } else {
181 return None;
182 }
183 }
184 };
185 *self = new_self;
186 Some(rv)
187 }
188
189 pub fn split_off_prefix(&mut self, n: usize) -> Result<Self, std::io::Error> {
191 let (rv, new_self) = match *self {
192 RawData::Single(single) => {
193 if single.len() < n {
194 return Err(std::io::ErrorKind::UnexpectedEof.into());
195 }
196 (RawData::Single(&single[..n]), RawData::Single(&single[n..]))
197 }
198 RawData::Split(left, right) => {
199 if n <= left.len() {
200 (
201 RawData::Single(&left[..n]),
202 if n < left.len() {
203 RawData::Split(&left[n..], right)
204 } else {
205 RawData::Single(right)
206 },
207 )
208 } else {
209 let remainder_len = n - left.len();
210 if remainder_len > right.len() {
211 return Err(std::io::ErrorKind::UnexpectedEof.into());
212 }
213 (
214 RawData::Split(left, &right[..remainder_len]),
215 RawData::Single(&right[remainder_len..]),
216 )
217 }
218 }
219 };
220 *self = new_self;
221 Ok(rv)
222 }
223
224 pub fn skip(&mut self, n: usize) -> Result<(), std::io::Error> {
225 *self = match *self {
226 RawData::Single(single) => {
227 if single.len() < n {
228 return Err(std::io::ErrorKind::UnexpectedEof.into());
229 }
230 RawData::Single(&single[n..])
231 }
232 RawData::Split(left, right) => {
233 if n < left.len() {
234 RawData::Split(&left[n..], right)
235 } else {
236 let remainder_len = n - left.len();
237 if remainder_len > right.len() {
238 return Err(std::io::ErrorKind::UnexpectedEof.into());
239 }
240 RawData::Single(&right[remainder_len..])
241 }
242 }
243 };
244 Ok(())
245 }
246
247 #[inline]
248 fn write_into(&self, target: &mut Vec<u8>) {
249 target.clear();
250 match *self {
251 RawData::Single(slice) => target.extend_from_slice(slice),
252 RawData::Split(first, second) => {
253 target.reserve(first.len() + second.len());
254 target.extend_from_slice(first);
255 target.extend_from_slice(second);
256 }
257 }
258 }
259
260 pub fn as_slice(&self) -> Cow<'a, [u8]> {
261 match *self {
262 RawData::Single(buffer) => buffer.into(),
263 RawData::Split(..) => {
264 let mut vec = Vec::new();
265 self.write_into(&mut vec);
266 vec.into()
267 }
268 }
269 }
270
271 pub fn get(&self, range: Range<usize>) -> Option<RawData<'a>> {
272 Some(match self {
273 RawData::Single(buffer) => RawData::Single(buffer.get(range)?),
274 RawData::Split(left, right) => {
275 if range.start >= left.len() {
276 RawData::Single(right.get(range.start - left.len()..range.end - left.len())?)
277 } else if range.end <= left.len() {
278 RawData::Single(left.get(range)?)
279 } else {
280 let left = left.get(range.start..)?;
281 let right = right.get(..min(range.end - left.len(), right.len()))?;
282 RawData::Split(left, right)
283 }
284 }
285 })
286 }
287
288 pub fn is_empty(&self) -> bool {
289 match *self {
290 RawData::Single(buffer) => buffer.is_empty(),
291 RawData::Split(left, right) => left.is_empty() && right.is_empty(),
292 }
293 }
294
295 pub fn len(&self) -> usize {
296 match *self {
297 RawData::Single(buffer) => buffer.len(),
298 RawData::Split(left, right) => left.len() + right.len(),
299 }
300 }
301}
302
303#[derive(Clone, Copy, PartialEq, Eq)]
304pub struct RawDataU64<'a> {
305 swapped_endian: bool,
306 raw_data: RawData<'a>,
307}
308
309pub fn is_swapped_endian<T: ByteOrder>() -> bool {
310 let mut buf = [0; 2];
311 T::write_u16(&mut buf, 0x1234);
312 u16::from_ne_bytes(buf) != 0x1234
313}
314
315impl<'a> RawDataU64<'a> {
316 #[inline]
317 pub fn from_raw_data<T: ByteOrder>(raw_data: RawData<'a>) -> Self {
318 RawDataU64 {
319 raw_data,
320 swapped_endian: is_swapped_endian::<T>(),
321 }
322 }
323
324 pub fn is_empty(&self) -> bool {
325 self.raw_data.is_empty()
326 }
327
328 pub fn len(&self) -> usize {
329 self.raw_data.len() / mem::size_of::<u64>()
330 }
331
332 pub fn get(&self, index: usize) -> Option<u64> {
333 let offset = index * mem::size_of::<u64>();
334 let mut data = self.raw_data;
335 data.skip(offset).ok()?;
336 let value = data.read_u64::<NativeEndian>().ok()?;
337 Some(if self.swapped_endian {
338 value.swap_bytes()
339 } else {
340 value
341 })
342 }
343}
344
345impl std::fmt::Debug for RawDataU64<'_> {
346 fn fmt(&self, fmt: &mut std::fmt::Formatter) -> Result<(), std::fmt::Error> {
347 let mut list = fmt.debug_list();
348 let mut data = self.raw_data;
349 while let Ok(value) = data.read_u64::<NativeEndian>() {
350 let value = if self.swapped_endian {
351 value.swap_bytes()
352 } else {
353 value
354 };
355 list.entry(&HexValue(value));
356 }
357
358 list.finish()
359 }
360}
361
362#[cfg(test)]
363mod test {
364 use super::RawData;
365
366 #[test]
367 fn test_reading_from_split() {
368 let full = b"CDEF===AB"; assert_eq!(full.len(), 9);
370 let mut split = RawData::Split(&full[7..9], &full[0..4]);
371 let mut dest = vec![0; 6];
372 split.read_exact(&mut dest).unwrap();
373 assert_eq!(&dest, b"ABCDEF");
374 }
375}