use crate::{BlockCount, BlockIdx, ClusterId};
use byteorder::{ByteOrder, LittleEndian};
#[cfg_attr(feature = "defmt-log", derive(defmt::Format))]
#[derive(Debug, Clone, Eq, PartialEq)]
pub enum FatSpecificInfo {
Fat16(Fat16Info),
Fat32(Fat32Info),
}
#[cfg_attr(feature = "defmt-log", derive(defmt::Format))]
#[derive(Debug, Clone, Eq, PartialEq)]
pub struct Fat32Info {
pub(crate) first_root_dir_cluster: ClusterId,
pub(crate) info_location: BlockIdx,
}
#[cfg_attr(feature = "defmt-log", derive(defmt::Format))]
#[derive(Debug, Clone, Eq, PartialEq)]
pub struct Fat16Info {
pub(crate) first_root_dir_block: BlockCount,
pub(crate) root_entries_count: u16,
}
pub struct InfoSector<'a> {
data: &'a [u8; 512],
}
impl<'a> InfoSector<'a> {
const LEAD_SIG: u32 = 0x4161_5252;
const STRUC_SIG: u32 = 0x6141_7272;
const TRAIL_SIG: u32 = 0xAA55_0000;
pub fn create_from_bytes(data: &[u8; 512]) -> Result<InfoSector, &'static str> {
let info = InfoSector { data };
if info.lead_sig() != Self::LEAD_SIG {
return Err("Bad lead signature on InfoSector");
}
if info.struc_sig() != Self::STRUC_SIG {
return Err("Bad struc signature on InfoSector");
}
if info.trail_sig() != Self::TRAIL_SIG {
return Err("Bad trail signature on InfoSector");
}
Ok(info)
}
define_field!(lead_sig, u32, 0);
define_field!(struc_sig, u32, 484);
define_field!(free_count, u32, 488);
define_field!(next_free, u32, 492);
define_field!(trail_sig, u32, 508);
pub fn free_clusters_count(&self) -> Option<u32> {
match self.free_count() {
0xFFFF_FFFF => None,
n => Some(n),
}
}
pub fn next_free_cluster(&self) -> Option<ClusterId> {
match self.next_free() {
0xFFFF_FFFF | 0 | 1 => None,
n => Some(ClusterId(n)),
}
}
}