use std::sync::Arc;
use super::{DESCRIPTOR, entry::MbrPartitionInfo};
use crate::{
ByteSourceHandle, Error, Result, SliceDataSource,
volumes::{VolumeRecord, VolumeSystem},
};
pub struct MbrVolumeSystem {
source: ByteSourceHandle,
bytes_per_sector: u32,
disk_signature: u32,
volumes: Vec<VolumeRecord>,
partitions: Vec<MbrPartitionInfo>,
}
impl MbrVolumeSystem {
pub fn new(
source: ByteSourceHandle, bytes_per_sector: u32, disk_signature: u32,
partitions: Vec<MbrPartitionInfo>,
) -> Self {
let volumes = partitions
.iter()
.map(|partition| partition.record.clone())
.collect();
Self {
source,
bytes_per_sector,
disk_signature,
volumes,
partitions,
}
}
pub fn disk_signature(&self) -> u32 {
self.disk_signature
}
pub fn partitions(&self) -> &[MbrPartitionInfo] {
&self.partitions
}
pub fn bytes_per_sector(&self) -> u32 {
self.bytes_per_sector
}
pub fn block_size(&self) -> u32 {
self.bytes_per_sector
}
pub fn volumes(&self) -> &[VolumeRecord] {
&self.volumes
}
pub fn open_volume(&self, index: usize) -> Result<ByteSourceHandle> {
let volume = self
.volumes
.get(index)
.ok_or_else(|| Error::not_found(format!("mbr volume index {index} is out of bounds")))?;
let slice: ByteSourceHandle = Arc::new(SliceDataSource::new(
self.source.clone(),
volume.span.byte_offset,
volume.span.byte_size,
));
Ok(slice)
}
}
impl VolumeSystem for MbrVolumeSystem {
fn descriptor(&self) -> crate::FormatDescriptor {
DESCRIPTOR
}
fn block_size(&self) -> u32 {
self.block_size()
}
fn volumes(&self) -> &[VolumeRecord] {
self.volumes()
}
fn open_volume(&self, index: usize) -> Result<ByteSourceHandle> {
self.open_volume(index)
}
}
crate::volumes::driver::impl_volume_system_data_source!(MbrVolumeSystem);