1use crate::region::fat::Entry;
2use crate::types::{ClusterID, SectorID};
3
4#[derive(Copy, Clone, Debug)]
5pub(crate) struct Info {
6    sector_size_shift: u8,
7    offset: u32,
8    length: u32,
9}
10
11#[cfg_attr(not(feature = "async"), deasync::deasync)]
12impl Info {
13    pub fn new(sector_size_shift: u8, offset: u32, length: u32) -> Self {
14        Self { sector_size_shift, offset, length }
15    }
16
17    pub fn fat_sector_id(&self, cluster_id: ClusterID) -> Option<SectorID> {
18        let index: u32 = cluster_id.into();
19        let sector_index = index / ((1 << self.sector_size_shift as u32) / 4);
20        if sector_index >= self.length {
21            return None;
22        }
23        Some(SectorID::from((self.offset + sector_index) as u64))
24    }
25
26    pub fn offset(&self, cluster_id: ClusterID) -> usize {
27        let index: u32 = cluster_id.into();
28        index as usize * 4 % (1 << self.sector_size_shift)
29    }
30
31    pub fn next_cluster_id(
32        &mut self,
33        sector: &[[u8; 512]],
34        cluster_id: ClusterID,
35    ) -> Result<Entry, u32> {
36        let index: u32 = cluster_id.into();
37        let offset = index as usize % ((1 << self.sector_size_shift) / 4);
38        let array: &[u32; 128] = unsafe { core::mem::transmute(§or[offset / 128]) };
39        Entry::try_from(u32::from_le(array[offset % 128]))
40    }
41}