fat32 0.2.0

FAT32 FileSystem Library
Documentation
use block_device::BlockDevice;
use crate::BUFFER_SIZE;
use crate::tool::read_le_u32;

#[derive(Debug, Copy, Clone)]
pub struct FAT<T>
    where T: BlockDevice + Clone + Copy,
          <T as BlockDevice>::Error: core::fmt::Debug {
    device: T,
    fat_offset: usize,
    start_cluster: u32,
    previous_cluster: u32,
    pub(crate) current_cluster: u32,
    next_cluster: Option<u32>,
    buffer: [u8; BUFFER_SIZE],
}

impl<T> FAT<T>
    where T: BlockDevice + Clone + Copy,
          <T as BlockDevice>::Error: core::fmt::Debug {
    pub(crate) fn new(cluster: u32, device: T, fat_offset: usize) -> Self {
        Self {
            device,
            fat_offset,
            start_cluster: cluster,
            previous_cluster: 0,
            current_cluster: 0,
            next_cluster: None,
            buffer: [0; BUFFER_SIZE],
        }
    }

    pub(crate) fn blank_cluster(&mut self) -> u32 {
        let mut cluster = 0;
        let mut done = false;

        for block in 0.. {
            self.device.read(&mut self.buffer,
                             self.fat_offset + block * BUFFER_SIZE,
                             1).unwrap();
            for i in (0..BUFFER_SIZE).step_by(4) {
                if read_le_u32(&self.buffer[i..i + 4]) == 0 {
                    done = true;
                    break;
                } else { cluster += 1; }
            }
            if done { break; }
        }
        cluster
    }

    pub(crate) fn write(&mut self, cluster: u32, value: u32) {
        let offset = (cluster as usize) * 4;
        let block_offset = offset / BUFFER_SIZE;
        let offset_left = offset % BUFFER_SIZE;
        let offset = self.fat_offset + block_offset * BUFFER_SIZE;
        let mut value: [u8; 4] = value.to_be_bytes();
        value.reverse();

        self.device.read(&mut self.buffer,
                         offset,
                         1).unwrap();
        self.buffer[offset_left..offset_left + 4].copy_from_slice(&value);
        self.device.write(&self.buffer,
                          offset,
                          1).unwrap();
    }

    pub(crate) fn refresh(&mut self, start_cluster: u32) {
        self.current_cluster = 0;
        self.start_cluster = start_cluster;
    }

    pub(crate) fn previous(&mut self) {
        if self.current_cluster != 0 {
            self.next_cluster = Some(self.current_cluster);
            self.current_cluster = self.previous_cluster;
        }
    }

    pub(crate) fn next_is_none(&self) -> bool {
        self.next_cluster.is_none()
    }

    fn current_cluster_usize(&self) -> usize {
        self.current_cluster as usize
    }
}

impl<T> Iterator for FAT<T>
    where T: BlockDevice + Clone + Copy,
          <T as BlockDevice>::Error: core::fmt::Debug {
    type Item = Self;

    fn next(&mut self) -> Option<Self::Item> {
        if self.current_cluster == 0 {
            self.current_cluster = self.start_cluster;
        } else {
            let next_cluster = self.next_cluster;
            if next_cluster.is_some() {
                self.previous_cluster = self.current_cluster;
                self.current_cluster = next_cluster.unwrap();
            } else {
                return None;
            }
        }

        let offset = self.current_cluster_usize() * 4;
        let block_offset = offset / BUFFER_SIZE;
        let offset_left = offset % BUFFER_SIZE;

        self.device.read(&mut self.buffer,
                         self.fat_offset + block_offset * BUFFER_SIZE,
                         1).unwrap();

        let next_cluster = read_le_u32(&self.buffer[offset_left..offset_left + 4]);
        let next_cluster = if next_cluster == 0x0FFFFFFF {
            None
        } else {
            Some(next_cluster)
        };

        self.next_cluster = next_cluster;

        Some(Self {
            next_cluster,
            ..(*self)
        })
    }
}