xref: /DragonOS/kernel/src/libs/vec_cursor.rs (revision 4454d1a2dd1f1078750151c028a794cfd9a04a1b)
1 #![allow(dead_code)]
2 
3 use core::mem::size_of;
4 
5 use alloc::vec::Vec;
6 
7 use crate::{
8     include::bindings::bindings::{E2BIG, EINVAL, EOVERFLOW},
9     io::SeekFrom,
10 };
11 
12 /// @brief 本模块用于为数组提供游标的功能,以简化其操作。
13 #[derive(Debug)]
14 pub struct VecCursor {
15     /// 游标管理的数据
16     data: Vec<u8>,
17     /// 游标的位置
18     pos: usize,
19 }
20 
21 impl VecCursor {
22     /// @brief 新建一个游标
23     pub fn new(data: Vec<u8>) -> Self {
24         return Self { data: data, pos: 0 };
25     }
26 
27     /// @brief 创建一个全0的cursor
28     pub fn zerod(length: usize) -> Self {
29         let mut result = VecCursor {
30             data: Vec::new(),
31             pos: 0,
32         };
33         result.data.resize(length, 0);
34         return result;
35     }
36 
37     /// @brief 获取游标管理的数据的可变引用
38     pub fn get_mut(&mut self) -> &mut Vec<u8> {
39         return &mut self.data;
40     }
41 
42     /// @brief 获取游标管理的数据的不可变引用
43     pub fn get_ref(&self) -> &Vec<u8> {
44         return &self.data;
45     }
46 
47     /// @brief 读取一个u8的数据(小端对齐)
48     pub fn read_u8(&mut self) -> Result<u8, i32> {
49         if self.pos >= self.data.len() {
50             return Err(-(E2BIG as i32));
51         }
52         self.pos += 1;
53         return Ok(self.data[self.pos - 1]);
54     }
55 
56     /// @brief 读取一个u16的数据(小端对齐)
57     pub fn read_u16(&mut self) -> Result<u16, i32> {
58         if self.pos + 2 > self.data.len() {
59             return Err(-(E2BIG as i32));
60         }
61         let mut res = 0u16;
62         res |= (self.data[self.pos] as u16) & 0xff;
63         self.pos += 1;
64         res |= ((self.data[self.pos] as u16) & 0xff) << 8;
65         self.pos += 1;
66 
67         return Ok(res);
68     }
69 
70     /// @brief 读取一个u32的数据(小端对齐)
71     pub fn read_u32(&mut self) -> Result<u32, i32> {
72         if self.pos + 4 > self.data.len() {
73             return Err(-(E2BIG as i32));
74         }
75         let mut res = 0u32;
76         for i in 0..4 {
77             res |= ((self.data[self.pos] as u32) & 0xff) << (8 * i);
78             self.pos += 1;
79         }
80 
81         return Ok(res);
82     }
83 
84     /// @brief 读取一个u64的数据(小端对齐)
85     pub fn read_u64(&mut self) -> Result<u64, i32> {
86         if self.pos + 8 > self.data.len() {
87             return Err(-(E2BIG as i32));
88         }
89         let mut res = 0u64;
90         for i in 0..8 {
91             res |= ((self.data[self.pos] as u64) & 0xff) << (8 * i);
92             self.pos += 1;
93         }
94 
95         return Ok(res);
96     }
97 
98     /// @brief 精确读取与buf同样大小的数据。
99     ///
100     /// @param buf 要读取到的目标缓冲区
101     ///
102     /// @return Ok(()) 成功读取
103     /// @retunr Err(-E2BIG) 没有这么多数据,读取失败
104     pub fn read_exact(&mut self, buf: &mut [u8]) -> Result<(), i32> {
105         if self.pos + buf.len() > self.data.len() {
106             return Err(-(E2BIG as i32));
107         }
108         buf.copy_from_slice(&self.data[self.pos..self.pos + buf.len()]);
109         self.pos += buf.len();
110         return Ok(());
111     }
112 
113     /// @brief 小端对齐,读取数据到u16数组.
114     ///
115     /// @param buf 目标u16数组
116     pub fn read_u16_into(&mut self, buf: &mut [u16]) -> Result<(), i32> {
117         if self.pos + buf.len() * size_of::<u16>() > self.data.len() * size_of::<u16>() {
118             return Err(-(E2BIG as i32));
119         }
120 
121         for i in 0..buf.len() {
122             buf[i] = self.read_u16()?;
123         }
124 
125         return Ok(());
126     }
127 
128     /// @brief 调整游标的位置
129     ///
130     /// @param 调整的相对值
131     ///
132     /// @return Ok(新的游标位置) 调整成功,返回新的游标位置
133     /// @return Err(-EOVERFLOW) 调整失败,游标超出正确的范围。(失败时游标位置不变)
134     pub fn seek(&mut self, origin: SeekFrom) -> Result<usize, i32> {
135         let pos: i64;
136         match origin {
137             SeekFrom::SeekSet(offset) => {
138                 pos = offset;
139             }
140             SeekFrom::SeekCurrent(offset) => {
141                 pos = self.pos as i64 + offset;
142             }
143             SeekFrom::SeekEnd(offset) => {
144                 // 请注意,此处的offset应小于等于0,否则肯定是不合法的
145                 pos = self.data.len() as i64 + offset;
146             }
147             SeekFrom::Invalid => {
148                 return Err(-(EINVAL as i32));
149             }
150         }
151 
152         if pos < 0 || pos > self.data.len() as i64 {
153             return Err(-(EOVERFLOW as i32));
154         }
155         self.pos = pos as usize;
156         return Ok(self.pos);
157     }
158 
159     /// @brief 写入一个u8的数据(小端对齐)
160     pub fn write_u8(&mut self, value: u8) -> Result<u8, i32> {
161         if self.pos >= self.data.len() {
162             return Err(-(E2BIG as i32));
163         }
164 
165         self.data[self.pos] = value;
166         self.pos += 1;
167 
168         return Ok(value);
169     }
170 
171     /// @brief 写入一个u16的数据(小端对齐)
172     pub fn write_u16(&mut self, value: u16) -> Result<u16, i32> {
173         if self.pos + 2 > self.data.len() {
174             return Err(-(E2BIG as i32));
175         }
176 
177         self.data[self.pos] = (value & 0xff) as u8;
178         self.pos += 1;
179         self.data[self.pos] = ((value >> 8) & 0xff) as u8;
180         self.pos += 1;
181 
182         return Ok(value);
183     }
184 
185     /// @brief 写入一个u32的数据(小端对齐)
186     pub fn write_u32(&mut self, value: u32) -> Result<u32, i32> {
187         if self.pos + 4 > self.data.len() {
188             return Err(-(E2BIG as i32));
189         }
190 
191         for i in 0..4 {
192             self.data[self.pos] = ((value >> (i * 8)) & 0xff) as u8;
193             self.pos += 1;
194         }
195 
196         return Ok(value);
197     }
198 
199     /// @brief 写入一个u64的数据(小端对齐)
200     pub fn write_u64(&mut self, value: u64) -> Result<u64, i32> {
201         if self.pos + 8 > self.data.len() {
202             return Err(-(E2BIG as i32));
203         }
204 
205         for i in 0..8 {
206             self.data[self.pos] = ((value >> (i * 8)) & 0xff) as u8;
207             self.pos += 1;
208         }
209 
210         return Ok(value);
211     }
212 
213     /// @brief 精确写入与buf同样大小的数据。
214     ///
215     /// @param buf 要写入到的目标缓冲区
216     ///
217     /// @return Ok(()) 成功写入
218     /// @retunr Err(-E2BIG) 没有这么多数据,写入失败
219     pub fn write_exact(&mut self, buf: &[u8]) -> Result<(), i32> {
220         if self.pos + buf.len() > self.data.len() {
221             return Err(-(E2BIG as i32));
222         }
223 
224         self.data[self.pos..self.pos + buf.len()].copy_from_slice(&buf[..]);
225         self.pos += buf.len();
226 
227         return Ok(());
228     }
229 
230     /// @brief 获取当前的数据切片
231     pub fn as_slice(&self) -> &[u8] {
232         return &self.data[..];
233     }
234 
235     /// @brief 获取可变数据切片
236     pub fn as_mut_slice(&mut self) -> &mut [u8] {
237         return &mut self.data[..];
238     }
239 
240     /// @brief 获取当前游标的位置
241     #[inline]
242     pub fn pos(&self) -> usize {
243         return self.pos;
244     }
245 
246     /// @brief 获取缓冲区数据的大小
247     #[inline]
248     pub fn len(&self) -> usize {
249         return self.data.len();
250     }
251 }
252