1#[derive(Copy, Clone, Debug, Eq, PartialEq, Hash)]
2pub enum Error {
3 BufferOverflow,
4 DataUnderflow,
5 InvalidFormat,
6}
7
8pub struct BytesIn<'a> {
9 data: &'a [u8],
10 offset: usize,
11}
12
13impl<'a> BytesIn<'a> {
14 pub const fn new(data: &'a [u8]) -> Self {
15 Self { data, offset: 0 }
16 }
17
18 pub fn is_empty(&self) -> bool {
19 self.offset == self.data.len()
20 }
21
22 pub fn offset(&self) -> usize {
23 self.offset
24 }
25
26 pub fn byte(&mut self) -> Result<u8, Error> {
27 self.arr::<1>().map(|arr| arr[0])
28 }
29
30 pub fn slice(&mut self, len: usize) -> Result<&'a [u8], Error> {
31 if len > self.data.len() - self.offset {
32 Err(Error::DataUnderflow)
33 } else {
34 let data = &self.data[self.offset..self.offset + len];
35 self.offset += len;
36
37 Ok(data)
38 }
39 }
40
41 pub fn arr<const N: usize>(&mut self) -> Result<[u8; N], Error> {
42 let slice = self.slice(N)?;
43
44 let mut data = [0; N];
45 data.copy_from_slice(slice);
46
47 Ok(data)
48 }
49
50 pub fn remaining(&mut self) -> &'a [u8] {
51 let data = unwrap!(self.slice(self.data.len() - self.offset), "Unreachable");
52
53 self.offset = self.data.len();
54
55 data
56 }
57
58 pub fn remaining_byte(&mut self) -> Result<u8, Error> {
59 Ok(self.remaining_arr::<1>()?[0])
60 }
61
62 pub fn remaining_arr<const N: usize>(&mut self) -> Result<[u8; N], Error> {
63 if self.data.len() - self.offset > N {
64 Err(Error::InvalidFormat)
65 } else {
66 self.arr::<N>()
67 }
68 }
69}
70
71pub struct BytesOut<'a> {
72 buf: &'a mut [u8],
73 offset: usize,
74}
75
76impl<'a> BytesOut<'a> {
77 pub fn new(buf: &'a mut [u8]) -> Self {
78 Self { buf, offset: 0 }
79 }
80
81 pub fn is_empty(&self) -> bool {
82 self.len() == 0
83 }
84
85 pub fn len(&self) -> usize {
86 self.offset
87 }
88
89 pub fn byte(&mut self, data: u8) -> Result<&mut Self, Error> {
90 self.push(&[data])
91 }
92
93 pub fn push(&mut self, data: &[u8]) -> Result<&mut Self, Error> {
94 if data.len() > self.buf.len() - self.offset {
95 Err(Error::BufferOverflow)
96 } else {
97 self.buf[self.offset..self.offset + data.len()].copy_from_slice(data);
98 self.offset += data.len();
99
100 Ok(self)
101 }
102 }
103}