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