1 // Copyright (c) 2023 Huawei Device Co., Ltd.
2 // Licensed under the Apache License, Version 2.0 (the "License");
3 // you may not use this file except in compliance with the License.
4 // You may obtain a copy of the License at
5 //
6 //     http://www.apache.org/licenses/LICENSE-2.0
7 //
8 // Unless required by applicable law or agreed to in writing, software
9 // distributed under the License is distributed on an "AS IS" BASIS,
10 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11 // See the License for the specific language governing permissions and
12 // limitations under the License.
13 
14 use std::convert::TryFrom;
15 use std::io::Read;
16 
17 pub type Result<T> = std::result::Result<T, Err>;
18 
19 // pub trait TransferData {
20 //     fn peek_u(&self, ty: &str, len: usize) -> &str;
21 //     fn get_u(&self, ty: &str, len: usize) -> &str;
22 //     fn put_u(&self, ty: &str, value: usize,len: usize) -> &mut [u8];
23 // }
24 //
25 // impl TransferData for Octets {
26 //     fn peek_u(&self, ty: &str, len: usize) -> &str {
27 //         todo!()
28 //     }
29 //
30 //     fn get_u(&self, ty: &str, len: usize) -> &str {
31 //         todo!()
32 //     }
33 //
34 //     fn put_u(&self, ty: &str, value: usize, len: usize) -> &mut [u8] {
35 //         todo!()
36 //     }
37 // }
38 // buf fragment splited by out offset
39 #[derive(Debug, PartialEq, Eq)]
40 pub struct ReadVarint<'a> {
41     buf: &'a [u8],
42 }
43 
44 impl<'a> ReadVarint<'a> {
new(buf: &'a [u8]) -> Self45     pub fn new(buf: &'a [u8]) -> Self {
46         ReadVarint { buf }
47     }
48 
into_u8(&mut self) -> Result<u8>49     pub fn into_u8(&mut self) -> Result<u8> {
50         const len: usize = 1;
51 
52         if self.buf.len() < len {
53             return Err(BufferTooShortError);
54         }
55         let bytes: [u8; len] = <[u8; len]>::try_from(self.buf[..len].as_ref()).unwrap();
56         if cfg!(target_endian = "big") {
57             let res: u8 = u8::from_be_bytes(bytes);
58             Ok(res)
59         } else {
60             let res: u8 = u8::from_le_bytes(bytes);
61             Ok(res)
62         }
63     }
64 
into_u16(&mut self) -> Result<u16>65     pub fn into_u16(&mut self) -> Result<u16> {
66         const len: usize = 2;
67 
68         if self.buf.len() < len {
69             return Err(BufferTooShortError);
70         }
71         let bytes: [u8; len] = <[u8; len]>::try_from(self.buf[..len].as_ref()).unwrap();
72         if cfg!(target_endian = "big") {
73             let res: u16 = u16::from_be_bytes(bytes);
74             Ok(res)
75         } else {
76             let res: u16 = u16::from_le_bytes(bytes);
77             Ok(res)
78         }
79     }
80 
into_u32(&mut self) -> Result<u32>81     pub fn into_u32(&mut self) -> Result<u32> {
82         const len: usize = 4;
83 
84         if self.buf.len() < len {
85             return Err(BufferTooShortError);
86         }
87         let bytes: [u8; len] = <[u8; len]>::try_from(self.buf[..len].as_ref()).unwrap();
88         if cfg!(target_endian = "big") {
89             let res: u32 = u32::from_be_bytes(bytes);
90             Ok(res)
91         } else {
92             let res: u32 = u32::from_le_bytes(bytes);
93             Ok(res)
94         }
95     }
96 
into_u64(&mut self) -> Result<u64>97     pub fn into_u64(&mut self) -> Result<u64> {
98         const len: usize = 8;
99 
100         if self.buf.len() < len {
101             return Err(BufferTooShortError);
102         }
103         let bytes: [u8; len] = <[u8; len]>::try_from(self.buf[..len].as_ref()).unwrap();
104         if cfg!(target_endian = "big") {
105             let res: u64 = u64::from_be_bytes(bytes);
106             Ok(res)
107         } else {
108             let res: u64 = u64::from_le_bytes(bytes);
109             Ok(res)
110         }
111     }
112 
113     /// Reads an unsigned variable-length integer in network byte-order from
114     /// the current offset and advances the buffer.
get_varint(&mut self) -> Result<u64>115     pub fn get_varint(&mut self) -> Result<u64> {
116         let first = self.into_u8()?;
117 
118         let len = varint_parse_len(first);
119 
120         if len > self.cap() {
121             return Err(BufferTooShortError);
122         }
123 
124         let out = match len {
125             1 => u64::from(self.into_u8()?),
126 
127             2 => u64::from(self.into_u16()? & 0x3fff),
128 
129             4 => u64::from(self.into_u32()? & 0x3fffffff),
130 
131             8 => self.into_u64()? & 0x3fffffffffffffff,
132 
133             _ => unreachable!(),
134         };
135 
136         Ok(out)
137     }
138 
139     /// Returns the remaining capacity in the buffer.
cap(&self) -> usize140     pub fn cap(&self) -> usize {
141         self.buf.len() - self.off
142     }
143 }
144 
145 // Component encoding status.
146 enum TokenStatus<T, E> {
147     // The current component is completely encoded.
148     Complete(T),
149     // The current component is partially encoded.
150     Partial(E),
151 }
152 
153 type TokenResult<T> = Result<TokenStatus<usize, T>>;
154 
155 struct WriteData<'a> {
156     src: &'a [u8],
157     src_idx: &'a mut usize,
158     dst: &'a mut [u8],
159 }
160 
161 impl<'a> WriteData<'a> {
new(src: &'a [u8], src_idx: &'a mut usize, dst: &'a mut [u8]) -> Self162     fn new(src: &'a [u8], src_idx: &'a mut usize, dst: &'a mut [u8]) -> Self {
163         WriteData { src, src_idx, dst }
164     }
165 
write(&mut self) -> TokenResult<usize>166     fn write(&mut self) -> TokenResult<usize> {
167         let src_idx = *self.src_idx;
168         let input_len = self.src.len() - src_idx;
169         let output_len = self.dst.len();
170         let num = (&self.src[src_idx..]).read(self.dst).unwrap();
171         if output_len >= input_len {
172             return Ok(TokenStatus::Complete(num));
173         }
174         *self.src_idx += num;
175         Ok(TokenStatus::Partial(num))
176     }
177 }
178 
179 pub struct WriteVarint<'a> {
180     src: &'a [u8],
181     src_idx: &'a mut usize,
182     dst: &'a mut [u8],
183 }
184 
185 impl<'a> WriteVarint<'a> {
186     // pub fn new(buf: &'a mut [u8]) -> Self {
187     //     WriteVarint { buf }
188     // }
new(src: &'a [u8], src_idx: &'a mut usize, dst: &'a mut [u8]) -> Self189     pub fn new(src: &'a [u8], src_idx: &'a mut usize, dst: &'a mut [u8]) -> Self {
190         // src需要从value转码过来
191         WriteVarint { src, src_idx, dst }
192     }
193 
194     /// Writes an unsigned 8-bit integer at the current offset and advances
195     /// the buffer.
write_u8(&mut self, value: u8) -> Result<usize>196     pub fn write_u8(&mut self, value: u8) -> Result<usize> {
197         const len: usize = 1;
198         // buf长度不够问题返回err,再由外层处理
199         if self.buf.len() != len {
200             return Err(BufferTooShortError);
201         }
202 
203         let bytes: [u8; len] = value.to_be_bytes();
204         self.buf.copy_from_slice(bytes.as_slice());
205         Ok(len)
206     }
207 
write_u16(&mut self, value: u16) -> Result<usize>208     pub fn write_u16(&mut self, value: u16) -> Result<usize> {
209         const len: usize = 2;
210         // buf长度不够问题返回err,再由外层处理
211         if self.buf.len() != len {
212             return Err(BufferTooShortError);
213         }
214 
215         let bytes: [u8; len] = value.to_be_bytes();
216         self.buf.copy_from_slice(bytes.as_slice());
217         Ok(len)
218     }
219 
write_u32(&mut self, value: u32) -> Result<usize>220     pub fn write_u32(&mut self, value: u32) -> Result<usize> {
221         const len: usize = 4;
222         // buf长度不够问题返回err,再由外层处理
223         if self.buf.len() != len {
224             return Err(BufferTooShortError);
225         }
226 
227         let bytes: [u8; len] = value.to_be_bytes();
228         self.buf.copy_from_slice(bytes.as_slice());
229         Ok(len)
230     }
231 
write_u64(&mut self, value: u64) -> Result<usize>232     pub fn write_u64(&mut self, value: u64) -> Result<usize> {
233         const len: usize = 8;
234         // buf长度不够问题返回err,再由外层处理
235         if self.buf.len() != len {
236             return Err(BufferTooShortError);
237         }
238 
239         let bytes: [u8; len] = value.to_be_bytes();
240         self.buf.copy_from_slice(bytes.as_slice());
241         Ok(len)
242     }
243 
244     /// Writes an unsigned variable-length integer in network byte-order at the
245     /// current offset and advances the buffer.
write_varint(&mut self, value: u64) -> Result<usize>246     pub fn write_varint(&mut self, value: u64) -> Result<usize> {
247         self.write_varint_with_len(value, varint_len(value))
248     }
249 
write_varint_with_len(&mut self, value: u64, len: usize) -> Result<usize>250     pub fn write_varint_with_len(&mut self, value: u64, len: usize) -> Result<usize> {
251         if self.cap() < len {
252             return Err(BufferTooShortError);
253         }
254 
255         let res = match len {
256             1 => self.write_u8(value as u8)?,
257 
258             2 => {
259                 let size = self.write_u16(value as u16)?;
260                 *self.buf[0] |= 0x40;
261                 size
262             }
263 
264             4 => {
265                 let size = self.write_u32(value as u32)?;
266                 *self.buf[0] |= 0x80;
267                 size
268             }
269 
270             8 => {
271                 let size = self.write_u64(value)?;
272                 *self.buf[0] |= 0xc0;
273                 size
274             }
275 
276             _ => panic!("value is too large for varint"),
277         };
278 
279         Ok(res)
280     }
281 }
282 
283 /// Returns how many bytes it would take to encode `v` as a variable-length
284 /// integer.
varint_len(v: u64) -> usize285 pub const fn varint_len(v: u64) -> usize {
286     match v {
287         0..=63 => 1,
288         64..=16383 => 2,
289         16384..=1_073_741_823 => 4,
290         1_073_741_824..=4_611_686_018_427_387_903 => 8,
291         _ => {unreachable!()}
292     }
293 }
294 
295 /// Returns how long the variable-length integer is, given its first byte.
varint_parse_len(byte: u8) -> usize296 pub const fn varint_parse_len(byte: u8) -> usize {
297     let byte = byte >> 6;
298     if byte <= 3 {
299         1 << byte
300     } else {
301         unreachable!()
302     }
303 }
304