pub(crate) fn iterate_dir<D, T, F>(
        &self,
        controller: &Controller<D, T>,
        dir: &Directory,
        mut func: F,
    ) -> Result<(), Error<D::Error>>
    where
        F: FnMut(&DirEntry),
        D: BlockDevice,
        T: TimeSource,
    {
        let mut first_dir_block_num = match dir.cluster {
            Cluster::ROOT_DIR => self.lba_start + self.first_root_dir_block,
            _ => self.cluster_to_block(dir.cluster),
        };
        let mut current_cluster = Some(dir.cluster);
        let dir_size = match dir.cluster {
            Cluster::ROOT_DIR => BlockCount(
                ((u32::from(self.root_entries_count) * 32) + (Block::LEN as u32 - 1))
                    / Block::LEN as u32,
            ),
            _ => BlockCount(u32::from(self.blocks_per_cluster)),
        };
        let mut blocks = [Block::new()];
        while let Some(cluster) = current_cluster {
            for block in first_dir_block_num.range(dir_size) {
                controller
                    .block_device
                    .read(&mut blocks, block, "read_dir")
                    .map_err(Error::DeviceError)?;
                for entry in 0..Block::LEN / OnDiskDirEntry::LEN {
                    let start = entry * OnDiskDirEntry::LEN;
                    let end = (entry + 1) * OnDiskDirEntry::LEN;
                    let dir_entry = OnDiskDirEntry::new(&blocks[0][start..end]);
                    if dir_entry.is_end() {
                        // Can quit early
                        return Ok(());
                    } else if dir_entry.is_valid() && !dir_entry.is_lfn() {
                        // Safe, since Block::LEN always fits on a u32
                        let start = u32::try_from(start).unwrap();
                        let entry = dir_entry.get_entry(FatType::Fat16, block, start);
                        func(&entry);
                    }
                }
            }
            if cluster != Cluster::ROOT_DIR {
                current_cluster = match self.next_cluster(controller, cluster) {
                    Ok(n) => {
                        first_dir_block_num = self.cluster_to_block(n);
                        Some(n)
                    }
                    _ => None,
                };
            } else {
                current_cluster = None;
            }
        }
        Ok(())
    }
/// Calls callback `func` with every valid entry in the given directory.
/// Useful for performing directory listings.
Calls callback `func` with every valid entry in the given directory.
Useful for performing directory listings.
Calls callback ` func ` with every valid entry in the given directory . Useful for performing directory listings .
pub(crate) fn iterate_dir<D, T, F>(
        &self,
        controller: &Controller<D, T>,
        dir: &Directory,
        mut func: F,
    ) -> Result<(), Error<D::Error>>
    where
        F: FnMut(&DirEntry),
        D: BlockDevice,
        T: TimeSource,
    {
        let mut first_dir_block_num = match dir.cluster {
            Cluster::ROOT_DIR => self.lba_start + self.first_root_dir_block,
            _ => self.cluster_to_block(dir.cluster),
        };
        let mut current_cluster = Some(dir.cluster);
        let dir_size = match dir.cluster {
            Cluster::ROOT_DIR => BlockCount(
                ((u32::from(self.root_entries_count) * 32) + (Block::LEN as u32 - 1))
                    / Block::LEN as u32,
            ),
            _ => BlockCount(u32::from(self.blocks_per_cluster)),
        };
        let mut blocks = [Block::new()];
        while let Some(cluster) = current_cluster {
            for block in first_dir_block_num.range(dir_size) {
                controller
                    .block_device
                    .read(&mut blocks, block, "read_dir")
                    .map_err(Error::DeviceError)?;
                for entry in 0..Block::LEN / OnDiskDirEntry::LEN {
                    let start = entry * OnDiskDirEntry::LEN;
                    let end = (entry + 1) * OnDiskDirEntry::LEN;
                    let dir_entry = OnDiskDirEntry::new(&blocks[0][start..end]);
                    if dir_entry.is_end() {
                        // Can quit early
                        return Ok(());
                    } else if dir_entry.is_valid() && !dir_entry.is_lfn() {
                        // Safe, since Block::LEN always fits on a u32
                        let start = u32::try_from(start).unwrap();
                        let entry = dir_entry.get_entry(FatType::Fat16, block, start);
                        func(&entry);
                    }
                }
            }
            if cluster != Cluster::ROOT_DIR {
                current_cluster = match self.next_cluster(controller, cluster) {
                    Ok(n) => {
                        first_dir_block_num = self.cluster_to_block(n);
                        Some(n)
                    }
                    _ => None,
                };
            } else {
                current_cluster = None;
            }
        }
        Ok(())
    }
pub ( crate ) fn iterate_dir < D , T , F > ( & self , controller : & Controller < D , T > , dir : & Directory , mut func : F , ) -> Result < ( ) , Error < D :: Error > > where F : FnMut ( & DirEntry ) , D : BlockDevice , T : TimeSource , { let mut first_dir_block_num = match dir . cluster { Cluster :: ROOT_DIR => self . lba_start + self . first_root_dir_block , _ => self . cluster_to_block ( dir . cluster ) , } ; let mut current_cluster = Some ( dir . cluster ) ; let dir_size = match dir . cluster { Cluster :: ROOT_DIR => BlockCount ( ( ( u32 :: from ( self . root_entries_count ) * 32 ) + ( Block :: LEN as u32 - 1 ) ) / Block :: LEN as u32 , ) , _ => BlockCount ( u32 :: from ( self . blocks_per_cluster ) ) , } ; let mut blocks = [ Block :: new ( ) ] ; while let Some ( cluster ) = current_cluster { for block in first_dir_block_num . range ( dir_size ) { controller . block_device . read ( & mut blocks , block , " " ) . map_err ( Error :: DeviceError ) ? ; for entry in 0 .. Block :: LEN / OnDiskDirEntry :: LEN { let start = entry * OnDiskDirEntry :: LEN ; let end = ( entry + 1 ) * OnDiskDirEntry :: LEN ; let dir_entry = OnDiskDirEntry :: new ( & blocks [ 0 ] [ start .. end ] ) ; if dir_entry . is_end ( ) { // Can quit early return Ok ( ( ) ) ; } else if dir_entry . is_valid ( ) && ! dir_entry . is_lfn ( ) { // Safe, since Block::LEN always fits on a u32 let start = u32 :: try_from ( start ) . unwrap ( ) ; let entry = dir_entry . get_entry ( FatType :: Fat16 , block , start ) ; func ( & entry ) ; } } } if cluster != Cluster :: ROOT_DIR { current_cluster = match self . next_cluster ( controller , cluster ) { Ok ( n ) => { first_dir_block_num = self . cluster_to_block ( n ) ; Some ( n ) } _ => None , } ; } else { current_cluster = None ; } } Ok ( ( ) ) }
Calls callback `func` with every valid entry in the given directory.
Calls callback ` func ` with every valid entry in the given directory .
&self
controller
&Controller<D, T>
dir
&Directory
func
F
&self
controller
&Controller<D, T>
dir
&Directory
func
F