1#![no_implicit_prelude]
21
22extern crate core;
23
24use core::clone::Clone;
25use core::iter::{IntoIterator, Iterator};
26use core::marker::Copy;
27use core::ops::FnMut;
28use core::option::Option::{self, None, Some};
29use core::result::Result::{self, Err, Ok};
30
31use crate::fs::{Block, BlockCache, BlockDevice, BlockPtr, Cache, Cluster, DIR_SIZE, DeviceError, DirEntry, DirEntryFull, Directory, Volume};
32
33pub struct Range {
34 sel: [RangeIndex; 0xA],
35 sum: u8,
36 index: u8,
37}
38pub struct RangeIter {
39 cur: RangeIndex,
40 range: Range,
41 pos: u8,
42}
43pub struct RangeIndex(u32, u32, u32);
44pub struct DirectoryIndex<'a, B: BlockDevice> {
45 vol: &'a Volume<'a, B>,
46 val: DirEntryFull,
47 buf: BlockPtr,
48 cache: BlockCache,
49 entry: u32,
50 block: u32,
51 blocks: u32,
52 cluster: u32,
53}
54pub struct DirectoryIter<'a, B: BlockDevice>(DirectoryIndex<'a, B>);
55pub struct DirectoryIterMut<'b, 'a: 'b, B: BlockDevice>(&'b mut DirectoryIndex<'a, B>);
56
57pub type RangeEntry = (u32, u32, bool, usize);
58
59impl Range {
60 #[inline]
61 pub(super) fn new() -> Range {
62 Range {
63 sel: [const { RangeIndex::new() }; 0xA],
64 sum: 0u8,
65 index: 0u8,
66 }
67 }
68
69 #[inline(always)]
70 pub fn blocks(&self) -> u8 {
71 self.index
72 }
73
74 #[inline(always)]
75 pub(super) fn clear(&mut self) {
76 (self.sum, self.index) = (0u8, 0u8)
77 }
78 #[inline(always)]
79 pub(super) fn finish(&mut self, c: u32, b: u32, e: u32) {
80 self.sel[self.index as usize].set(c, b, e);
81 }
82 pub(super) fn mark(&mut self, c: u32, b: u32, e: u32) -> u8 {
83 if self.index == 0 {
84 self.sel[0].set(c, b, e);
85 (self.index, self.sum) = (1, 1);
86 } else {
87 let v = &mut self.sel[self.index as usize - 1];
88 if v.0 != c || v.1 != b {
89 self.sel[self.index as usize].set(c, b, e);
90 self.index += 1;
91 }
92 self.sum += 1;
93 }
94 self.sum
95 }
96}
97impl RangeIter {
98 fn is_next(&self) -> bool {
99 if self.cur.2 >= (Block::SIZE as u32 / DIR_SIZE as u32) {
100 return true;
101 }
102 if self.pos + 1 < self.range.index {
103 return false;
104 }
105 let v = self.range.sel[self.pos as usize + 1].2;
106 v == 0 || self.cur.2 > v
107 }
108 fn next_entry(&mut self) -> Option<RangeEntry> {
109 let n = if self.is_next() {
110 self.pos += 1;
111 if self.pos >= self.range.index {
112 return None;
113 }
114 self.cur = self.range.sel[self.pos as usize];
115 true
116 } else {
117 false || self.range.sel[self.pos as usize].2 == self.cur.2
118 };
119 let e = self.cur.2 as usize;
120 self.cur.2 += 1;
121 Some((self.cur.0, self.cur.1, n, e))
122 }
123}
124impl RangeIndex {
125 #[inline(always)]
126 const fn new() -> RangeIndex {
127 RangeIndex(0u32, 0u32, 0u32)
128 }
129
130 #[inline(always)]
131 fn set(&mut self, c: u32, b: u32, e: u32) {
132 (self.0, self.1, self.2) = (c, b, e);
133 }
134}
135impl<'b, 'a: 'b, B: BlockDevice> DirectoryIndex<'a, B> {
136 #[inline(always)]
137 pub(super) fn new(vol: &'a Volume<'a, B>) -> DirectoryIndex<'a, B> {
138 DirectoryIndex {
139 vol,
140 val: DirEntryFull::new(),
141 buf: Cache::block_b(),
142 cache: BlockCache::new(),
143 entry: 0u32,
144 block: 0u32,
145 blocks: 0u32,
146 cluster: 0u32,
147 }
148 }
149
150 #[inline(always)]
153 pub fn into_iter_mut(&'b mut self) -> DirectoryIterMut<'b, 'a, B> {
154 DirectoryIterMut(self)
155 }
156 #[inline(always)]
157 pub fn reset(&mut self, dir: &Directory<'a, B>) -> Result<(), DeviceError> {
158 self.setup(dir.cluster())
159 }
160 #[inline]
163 pub fn iter(&mut self, mut func: impl FnMut(&DirEntryFull)) -> Result<(), DeviceError> {
164 loop {
165 match self.next(true)? {
166 Some(v) => func(v),
167 None => break,
168 }
169 }
170 Ok(())
171 }
172 #[inline]
173 pub fn find(&mut self, mut func: impl FnMut(&DirEntryFull) -> bool) -> Result<Option<DirEntry>, DeviceError> {
174 loop {
175 match self.next(true)? {
176 Some(v) if func(v) => return Ok(Some(v.entry())),
177 Some(_) => continue,
178 None => break,
179 }
180 }
181 Ok(None)
182 }
183
184 pub(super) fn setup(&mut self, start: Cluster) -> Result<(), DeviceError> {
185 self.entry = 0u32;
186 self.cache.clear();
187 self.cluster = start.unwrap_or_else(|| self.vol.man.root());
188 let i = self.vol.man.block_pos_at(self.cluster);
189 self.block = i;
190 self.blocks = i + self.vol.man.entries_count(start);
191 self.cache.read_single(self.vol.dev, &mut self.buf, i)?;
192 Ok(())
193 }
194
195 #[inline(always)]
196 fn is_loop_done(&self) -> bool {
197 self.entry >= (Block::SIZE / DIR_SIZE) as u32
198 }
199 fn is_complete(&mut self) -> Result<bool, DeviceError> {
200 if !self.is_loop_done() {
201 return Ok(false);
202 }
203 (self.entry, self.block) = (0, self.block + 1);
204 if self.block <= self.blocks {
205 return self
206 .cache
207 .read_single(self.vol.dev, &mut self.buf, self.block)
208 .map(|_| false);
209 }
210 self.cluster = match self
211 .vol
212 .man
213 .cluster_next(self.vol.dev, &mut self.buf, &mut self.cache, self.cluster)?
214 {
215 None => return Ok(true),
216 Some(v) => v,
217 };
218 let i = self.vol.man.block_pos_at(self.cluster);
219 (self.block, self.blocks) = (i, i + self.vol.man.blocks.blocks_per_cluster());
220 Ok(false)
221 }
222 fn next(&'b mut self, r: bool) -> Result<Option<&'b mut DirEntryFull>, DeviceError> {
223 if self.is_complete()? {
224 return Ok(None);
225 }
226 if r {
227 self.val.reset();
230 }
231 while !self.is_loop_done() {
232 let s = self.entry as usize * DIR_SIZE;
233 if self.buf[s] == 0 {
234 return Ok(None);
235 }
236 self.entry += 1;
237 if self.buf[s + 0xB] & 0xF == 0xF {
238 self.val.fill(&self.buf[s..]);
239 continue;
240 }
241 if self.buf[s + 0xB] & 0x8 != 0 && self.buf[s + 0x1C] == 0 {
242 continue;
243 }
244 if self.buf[s] != 0xE5 {
245 self.val.load(&self.vol.man.ver, &self.buf[s..], self.block, s as u32);
246 return Ok(Some(&mut self.val));
251 }
252 }
253 self.next(false)
254 }
255}
256
257impl Copy for RangeIndex {}
258impl Clone for RangeIndex {
259 #[inline(always)]
260 fn clone(&self) -> RangeIndex {
261 RangeIndex(self.0, self.1, self.2)
262 }
263}
264
265impl Iterator for RangeIter {
266 type Item = RangeEntry;
267
268 #[inline(always)]
269 fn next(&mut self) -> Option<RangeEntry> {
270 self.next_entry()
271 }
272}
273
274impl Clone for Range {
275 #[inline(always)]
276 fn clone(&self) -> Range {
277 Range {
278 sel: self.sel.clone(),
279 sum: self.sum,
280 index: self.index,
281 }
282 }
283}
284impl IntoIterator for Range {
285 type Item = RangeEntry;
286 type IntoIter = RangeIter;
287
288 #[inline(always)]
289 fn into_iter(self) -> RangeIter {
290 RangeIter {
291 pos: 0u8,
292 cur: self.sel[0],
293 range: self,
294 }
295 }
296}
297
298impl<'a, B: BlockDevice> IntoIterator for DirectoryIndex<'a, B> {
299 type IntoIter = DirectoryIter<'a, B>;
300 type Item = Result<DirEntry, DeviceError>;
301
302 #[inline(always)]
303 fn into_iter(self) -> DirectoryIter<'a, B> {
304 DirectoryIter(self)
305 }
306}
307impl<'b, 'a: 'b, B: BlockDevice> IntoIterator for &'b mut DirectoryIndex<'a, B> {
308 type IntoIter = DirectoryIterMut<'b, 'a, B>;
309 type Item = Result<DirEntry, DeviceError>;
310
311 #[inline(always)]
312 fn into_iter(self) -> DirectoryIterMut<'b, 'a, B> {
313 DirectoryIterMut(self)
314 }
315}
316
317impl<'a, B: BlockDevice> Iterator for DirectoryIter<'a, B> {
318 type Item = Result<DirEntry, DeviceError>;
319
320 #[inline]
321 fn next(&mut self) -> Option<Result<DirEntry, DeviceError>> {
322 match self.0.next(true) {
323 Ok(None) => None,
324 Ok(Some(v)) => Some(Ok(v.entry())),
325 Err(e) => Some(Err(e)),
326 }
327 }
328}
329
330impl<'b, 'a: 'b, B: BlockDevice> Iterator for DirectoryIterMut<'b, 'a, B> {
331 type Item = Result<DirEntry, DeviceError>;
332
333 #[inline]
334 fn next(&mut self) -> Option<Result<DirEntry, DeviceError>> {
335 match self.0.next(true) {
336 Ok(None) => None,
337 Ok(Some(v)) => Some(Ok(v.entry())),
338 Err(e) => Some(Err(e)),
339 }
340 }
341}