• 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 trait Write {
write(&self, w: &mut Writer) where Self: Sized16     fn write(&self, w: &mut Writer)
17     where
18         Self: Sized;
19 }
20 
21 pub struct Writer {
22     vec: Vec<u8>,
23 }
24 
25 impl Writer {
new(vec: Vec<u8>) -> Self26     pub(crate) fn new(vec: Vec<u8>) -> Self {
27         Self { vec }
28     }
29 
into_vec(self) -> Vec<u8>30     pub(crate) fn into_vec(self) -> Vec<u8> {
31         self.vec
32     }
33 
put(&mut self, slice: &[u8])34     pub(crate) fn put(&mut self, slice: &[u8]) {
35         self.vec.extend_from_slice(slice);
36     }
37 
write<T: Write>(&mut self, v: &T)38     pub(crate) fn write<T: Write>(&mut self, v: &T) {
39         v.write(self)
40     }
41 
write_u8(&mut self, v: u8)42     pub(crate) fn write_u8(&mut self, v: u8) {
43         self.write_u32::<1>(v.into());
44     }
45 
write_u16(&mut self, v: u16)46     pub(crate) fn write_u16(&mut self, v: u16) {
47         self.write_u32::<2>(v.into());
48     }
49 
write_u32<const N: usize>(&mut self, mut v: u32)50     pub(crate) fn write_u32<const N: usize>(&mut self, mut v: u32) {
51         for _ in 0..N {
52             self.vec.push((v & 0xff) as u8);
53             v >>= 8;
54         }
55     }
56 
write_bytes<const N: usize>(&mut self, bytes: &[u8; N])57     pub(crate) fn write_bytes<const N: usize>(&mut self, bytes: &[u8; N]) {
58         self.put(bytes);
59     }
60 }
61 
62 impl Write for Vec<u8> {
write(&self, w: &mut Writer)63     fn write(&self, w: &mut Writer) {
64         w.write_u8(self.len().try_into().unwrap());
65         w.put(self);
66     }
67 }
68 
69 impl Write for Vec<u16> {
write(&self, w: &mut Writer)70     fn write(&self, w: &mut Writer) {
71         w.write_u8(self.len().try_into().unwrap());
72         for item in self {
73             w.write_u16(*item);
74         }
75     }
76 }
77 
78 impl<T: Write> Write for Vec<T> {
write(&self, w: &mut Writer)79     fn write(&self, w: &mut Writer) {
80         w.write_u8(self.len().try_into().unwrap());
81         for item in self {
82             w.write(item);
83         }
84     }
85 }
86 
87 macro_rules! pack {
88     ( $( ($x:expr, $n:expr) ),* ) => {
89         {
90             let mut y = 0;
91             let mut _shl = 0;
92             $(
93                 assert!($x & !((1 << $n) - 1) == 0);
94                 y |= ($x << _shl);
95                 _shl += $n;
96             )*
97             y
98         }
99     };
100     ( $x:expr, $n:expr ) => { pack!(($x, $n)) };
101 }
102 
103 pub(crate) use pack;
104