• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 use ylong_runtime::iter::parallel::ParSplit;
18 
19 use crate::h3::error::CommonError::BufferTooShort;
20 use crate::h3::error::{EncodeError, H3Error};
21 
22 pub type Result<T> = std::result::Result<T, H3Error>;
23 
24 macro_rules! peek_bytes {
25     ($buf: expr, $ty: ty, $len: expr) => {{
26         if $buf.len() < $len {
27             return Err(H3Error::Serialize(BufferTooShort));
28         }
29         let bytes: [u8; $len] = <[u8; $len]>::try_from($buf[..$len].as_ref()).unwrap();
30         let res = <$ty>::from_be_bytes(bytes);
31         Ok(res)
32     }};
33 }
34 
35 macro_rules! poll_bytes {
36     ($this: expr, $ty: ty, $len: expr) => {{
37         let res = peek_bytes!($this.buf[$this.idx..], $ty, $len);
38         $this.idx += $len;
39         res
40     }};
41 }
42 
43 #[derive(Debug, PartialEq, Eq)]
44 pub struct ReadableBytes<'a> {
45     buf: &'a [u8],
46     idx: usize,
47 }
48 
49 impl<'a> ReadableBytes<'a> {
from(buf: &'a [u8]) -> Self50     pub fn from(buf: &'a [u8]) -> Self {
51         ReadableBytes { buf, idx: 0 }
52     }
53 
peek_u8(&mut self) -> Result<u8>54     pub(crate) fn peek_u8(&mut self) -> Result<u8> {
55         peek_bytes!(self.buf[self.idx..], u8, 1)
56     }
57 
poll_u8(&mut self) -> Result<u8>58     pub fn poll_u8(&mut self) -> Result<u8> {
59         poll_bytes!(self, u8, 1)
60     }
61 
poll_u16(&mut self) -> Result<u16>62     pub fn poll_u16(&mut self) -> Result<u16> {
63         poll_bytes!(self, u16, 2)
64     }
65 
poll_u32(&mut self) -> Result<u32>66     pub fn poll_u32(&mut self) -> Result<u32> {
67         poll_bytes!(self, u32, 4)
68     }
69 
poll_u64(&mut self) -> Result<u64>70     pub fn poll_u64(&mut self) -> Result<u64> {
71         poll_bytes!(self, u64, 8)
72     }
73 
74     /// Reads an unsigned variable-length integer in network byte-order from
75     /// the current offset and advances the buffer.
get_varint(&mut self) -> Result<u64>76     pub fn get_varint(&mut self) -> Result<u64> {
77         let first = self.peek_u8()?;
78         let len = parse_varint_len(first);
79         if len > self.cap() {
80             return Err(BufferTooShort.into());
81         }
82         let out = match len {
83             1 => u64::from(self.poll_u8()?),
84 
85             2 => u64::from(self.poll_u16()? & 0x3fff),
86 
87             4 => u64::from(self.poll_u32()? & 0x3fffffff),
88 
89             8 => self.poll_u64()? & 0x3fffffffffffffff,
90 
91             _ => unreachable!(),
92         };
93 
94         Ok(out)
95     }
96 
97     /// Returns the remaining capacity in the buffer.
cap(&self) -> usize98     pub fn cap(&self) -> usize {
99         self.buf.len() - self.idx
100     }
101 
index(&self) -> usize102     pub fn index(&self) -> usize {
103         self.idx
104     }
105 
remaining(&self) -> &[u8]106     pub fn remaining(&self) -> &[u8] {
107         &self.buf[self.idx..]
108     }
109 
slice(&mut self, length: usize) -> Result<&[u8]>110     pub fn slice(&mut self, length: usize) -> Result<&[u8]> {
111         if self.cap() < length {
112             Err(BufferTooShort.into())
113         } else {
114             let curr = self.idx;
115             self.idx += length;
116             Ok(&self.buf[curr..self.idx])
117         }
118     }
119 }
120 
121 macro_rules! write_bytes {
122     ($this: expr, $value: expr, $len: expr) => {{
123         // buf长度不够问题返回err,再由外层处理
124         if $this.remaining() < $len {
125             return Err(BufferTooShort.into());
126         }
127 
128         let mut bytes: [u8; $len] = $value.to_be_bytes();
129         match $len {
130             1 => {}
131             2 => bytes[0] |= 0x40,
132             4 => bytes[0] |= 0x80,
133             8 => bytes[0] |= 0xC0,
134             _ => unreachable!(),
135         }
136         $this.bytes[$this.idx..$this.idx + $len].copy_from_slice(bytes.as_slice());
137         $this.idx_add($len);
138         Ok($len)
139     }};
140 }
141 
142 pub struct WritableBytes<'a> {
143     bytes: &'a mut [u8],
144     idx: usize,
145 }
146 
147 impl<'a> WritableBytes<'a> {
from(bytes: &'a mut [u8]) -> WritableBytes<'a>148     pub fn from(bytes: &'a mut [u8]) -> WritableBytes<'a> {
149         Self { bytes, idx: 0 }
150     }
151 
remaining(&self) -> usize152     pub fn remaining(&self) -> usize {
153         self.bytes.len() - self.idx
154     }
155 
index(&self) -> usize156     pub fn index(&self) -> usize {
157         self.idx
158     }
159 
idx_add(&mut self, offset: usize)160     pub fn idx_add(&mut self, offset: usize) {
161         self.idx += offset
162     }
163 
164     /// Writes an unsigned 8-bit integer at the current offset and advances
165     /// the buffer.
write_u8(&mut self, value: u8) -> Result<usize>166     pub fn write_u8(&mut self, value: u8) -> Result<usize> {
167         write_bytes!(self, value, 1)
168     }
169 
write_u16(&mut self, value: u16) -> Result<usize>170     pub fn write_u16(&mut self, value: u16) -> Result<usize> {
171         write_bytes!(self, value, 2)
172     }
173 
write_u32(&mut self, value: u32) -> Result<usize>174     pub fn write_u32(&mut self, value: u32) -> Result<usize> {
175         write_bytes!(self, value, 4)
176     }
177 
write_u64(&mut self, value: u64) -> Result<usize>178     pub fn write_u64(&mut self, value: u64) -> Result<usize> {
179         write_bytes!(self, value, 8)
180     }
181 
182     /// Writes an unsigned variable-length integer in network byte-order at the
183     /// current offset and advances the buffer.
write_varint(&mut self, value: u64) -> Result<usize>184     pub fn write_varint(&mut self, value: u64) -> Result<usize> {
185         self.write_varint_with_len(value, varint_len(value))
186     }
187 
write_varint_with_len(&mut self, value: u64, len: usize) -> Result<usize>188     fn write_varint_with_len(&mut self, value: u64, len: usize) -> Result<usize> {
189         if self.remaining() < len {
190             return Err(BufferTooShort.into());
191         }
192         match len {
193             1 => self.write_u8(value as u8),
194             2 => self.write_u16(value as u16),
195             4 => self.write_u32(value as u32),
196             8 => self.write_u64(value),
197             _ => panic!("value is too large for varint"),
198         }
199     }
200 }
201 
202 /// Returns how many bytes it would take to encode `v` as a variable-length
203 /// integer.
varint_len(v: u64) -> usize204 pub const fn varint_len(v: u64) -> usize {
205     match v {
206         0..=63 => 1,
207         64..=16383 => 2,
208         16384..=1_073_741_823 => 4,
209         1_073_741_824..=4_611_686_018_427_387_903 => 8,
210         _ => {
211             unreachable!()
212         }
213     }
214 }
215 
216 /// Returns how long the variable-length integer is, given its first byte.
parse_varint_len(byte: u8) -> usize217 pub const fn parse_varint_len(byte: u8) -> usize {
218     let pre = byte >> 6;
219     if pre <= 3 {
220         1 << pre
221     } else {
222         unreachable!()
223     }
224 }
225 
226 #[cfg(test)]
227 mod h3_octets {
228     use crate::h3::octets::{ReadableBytes, WritableBytes};
229 
230     /// UT test cases for `ReadableBytes::get_varint` .
231     ///
232     /// # Brief
233     /// 1. Creates a buf with variable-length integer encoded bytes.
234     /// 2. Creates a `ReadableBytes` with the buf.
235     /// 3. Calls the get_varint method to get the value.
236     /// 4. Checks whether the result is correct.
237     #[test]
ut_readable_bytes()238     fn ut_readable_bytes() {
239         let bytes = [
240             0x3F, 0x7F, 0xFF, 0xBF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
241             0xFF,
242         ];
243         let mut readable = ReadableBytes::from(&bytes);
244         assert_eq!(readable.get_varint().unwrap(), 63);
245         assert_eq!(readable.get_varint().unwrap(), 16383);
246         assert_eq!(readable.get_varint().unwrap(), 1_073_741_823);
247         assert_eq!(readable.get_varint().unwrap(), 4_611_686_018_427_387_903);
248         assert_eq!(readable.index(), 15);
249     }
250 
251     /// UT test cases for `WritableBytes::write_varint` .
252     ///
253     /// # Brief
254     /// 1. Creates a result buf with variable-length integer encoded bytes.
255     /// 2. Creates a `WritableBytes` with empty buf.
256     /// 3. Calls the write_varint method to write integers.
257     /// 4. Checks whether the result is correct.
258     #[test]
ut_writable_bytes()259     fn ut_writable_bytes() {
260         let bytes = [
261             0x3F, 0x7F, 0xFF, 0xBF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
262             0xFF,
263         ];
264         let mut buf = [0u8; 15];
265         let mut writable = WritableBytes::from(&mut buf);
266         assert_eq!(writable.write_varint(63).unwrap(), 1);
267         assert_eq!(writable.write_varint(16383).unwrap(), 2);
268         assert_eq!(writable.write_varint(1_073_741_823).unwrap(), 4);
269         assert_eq!(writable.write_varint(4_611_686_018_427_387_903).unwrap(), 8);
270         assert_eq!(writable.index(), 15);
271         assert_eq!(buf, bytes);
272     }
273 }
274