• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2024, The Android Open Source Project
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 //     http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14 
15 pub(crate) trait Read {
read(r: &mut Reader) -> Option<Self> where Self: Sized16     fn read(r: &mut Reader) -> Option<Self>
17     where
18         Self: Sized;
19 }
20 
21 pub(crate) struct Reader<'a> {
22     data: &'a [u8],
23     pos: usize,
24 }
25 
26 impl<'a> Reader<'a> {
new(data: &'a [u8]) -> Self27     pub(crate) fn new(data: &'a [u8]) -> Self {
28         Self { data, pos: 0 }
29     }
30 
get(&mut self, n: usize) -> Option<&'a [u8]>31     pub(crate) fn get(&mut self, n: usize) -> Option<&'a [u8]> {
32         if self.pos + n > self.data.len() {
33             return None;
34         }
35         let old_pos = self.pos;
36         self.pos += n;
37         Some(&self.data[old_pos..self.pos])
38     }
39 
read<T: Read>(&mut self) -> Option<T>40     pub(crate) fn read<T: Read>(&mut self) -> Option<T> {
41         T::read(self)
42     }
43 
read_u8(&mut self) -> Option<u8>44     pub(crate) fn read_u8(&mut self) -> Option<u8> {
45         Some(self.read_u32::<1>()? as u8)
46     }
47 
read_u16(&mut self) -> Option<u16>48     pub(crate) fn read_u16(&mut self) -> Option<u16> {
49         Some(self.read_u32::<2>()? as u16)
50     }
51 
read_u32<const N: usize>(&mut self) -> Option<u32>52     pub(crate) fn read_u32<const N: usize>(&mut self) -> Option<u32> {
53         let data_it = self.get(N)?.iter().enumerate();
54         Some(data_it.fold(0u32, |v, (i, byte)| v | (*byte as u32) << (i * 8)))
55     }
56 
read_bytes<const N: usize>(&mut self) -> Option<[u8; N]>57     pub(crate) fn read_bytes<const N: usize>(&mut self) -> Option<[u8; N]> {
58         Some(<[u8; N]>::try_from(self.get(N)?).unwrap())
59     }
60 }
61 
62 impl Read for Vec<u8> {
read(r: &mut Reader) -> Option<Self>63     fn read(r: &mut Reader) -> Option<Self> {
64         let len = r.read_u8()? as usize;
65         Some(Vec::from(r.get(len)?))
66     }
67 }
68 
69 impl Read for Vec<u16> {
read(r: &mut Reader) -> Option<Self>70     fn read(r: &mut Reader) -> Option<Self> {
71         let len = r.read_u8()? as usize;
72         let vec: Vec<_> = (0..len).map_while(|_| r.read_u16()).collect();
73         Some(vec).take_if(|v| v.len() == len)
74     }
75 }
76 
77 impl<T: Read> Read for Vec<T> {
read(r: &mut Reader) -> Option<Self>78     fn read(r: &mut Reader) -> Option<Self> {
79         let len = r.read_u8()? as usize;
80         let vec: Vec<_> = (0..len).map_while(|_| r.read()).collect();
81         Some(vec).take_if(|v| v.len() == len)
82     }
83 }
84 
85 macro_rules! unpack {
86     ($v:expr, ($( $n:expr ),*)) => {
87         {
88             let mut _x = $v;
89             ($({
90                 let y = _x & ((1 << $n) - 1);
91                 _x >>= $n;
92                 y
93             }),*)
94         }
95     };
96     ($v:expr, $n:expr) => { unpack!($v, ($n)) };
97 }
98 
99 pub(crate) use unpack;
100