pub mod bitstream;
pub mod fluxstream;
pub mod metasector;
use crate::bitstream::TrackDataStream;
use crate::diskimage::{
ReadSectorResult, ReadTrackResult, RwSectorScope, ScanSectorResult, SectorDescriptor, WriteSectorResult,
};
use crate::structure_parsers::system34::System34Standard;
use crate::structure_parsers::DiskStructureMetadata;
use crate::track::bitstream::BitStreamTrack;
use crate::track::fluxstream::FluxStreamTrack;
use crate::track::metasector::MetaSectorTrack;
use crate::{
DiskCh, DiskChs, DiskChsn, DiskDataEncoding, DiskDataRate, DiskDataResolution, DiskDensity, DiskImageError,
DiskRpm, SectorMapEntry,
};
use sha1_smol::Digest;
use std::any::Any;
#[derive(Debug)]
pub struct TrackInfo {
pub encoding: DiskDataEncoding,
pub data_rate: DiskDataRate,
pub density: Option<DiskDensity>,
pub rpm: Option<DiskRpm>,
pub bit_length: usize,
pub sector_ct: usize,
}
pub enum TrackSectorScanResult {
Found {
element_start: usize,
element_end: usize,
sector_chsn: DiskChsn,
address_crc_valid: bool,
data_crc_valid: bool,
deleted: bool,
no_dam: bool,
},
NotFound {
wrong_cylinder: bool,
bad_cylinder: bool,
wrong_head: bool,
},
#[allow(dead_code)] Incompatible,
}
#[derive(Debug, Default)]
pub struct TrackConsistency {
pub bad_data_crc: bool,
pub bad_address_crc: bool,
pub deleted_data: bool,
pub no_dam: bool,
pub consistent_sector_size: Option<u8>,
pub nonconsecutive_sectors: bool,
pub overlapping_sectors: bool,
pub sector_crossing_index: bool,
pub sector_ct: usize,
}
impl TrackConsistency {
pub fn join(&mut self, other: &TrackConsistency) {
self.bad_data_crc |= other.bad_data_crc;
self.bad_address_crc |= other.bad_address_crc;
self.deleted_data |= other.deleted_data;
self.no_dam |= other.no_dam;
self.nonconsecutive_sectors |= other.nonconsecutive_sectors;
self.overlapping_sectors |= other.overlapping_sectors;
self.sector_crossing_index |= other.sector_crossing_index;
if other.consistent_sector_size.is_none() {
self.consistent_sector_size = None;
}
}
}
pub trait Track: Any {
fn resolution(&self) -> DiskDataResolution;
fn as_any(&self) -> &dyn Any;
fn as_any_mut(&mut self) -> &mut dyn Any;
fn as_metasector_track(&self) -> Option<&MetaSectorTrack>;
fn as_bitstream_track(&self) -> Option<&BitStreamTrack>;
fn as_fluxstream_track(&self) -> Option<&FluxStreamTrack>;
fn as_fluxstream_track_mut(&mut self) -> Option<&mut FluxStreamTrack>;
fn ch(&self) -> DiskCh;
fn set_ch(&mut self, ch: DiskCh);
fn encoding(&self) -> DiskDataEncoding;
fn info(&self) -> TrackInfo;
fn metadata(&self) -> Option<&DiskStructureMetadata>;
fn get_sector_ct(&self) -> usize;
fn has_sector_id(&self, id: u8, id_chsn: Option<DiskChsn>) -> bool;
fn get_sector_list(&self) -> Vec<SectorMapEntry>;
fn add_sector(&mut self, sd: &SectorDescriptor, alternate: bool) -> Result<(), DiskImageError>;
fn read_sector(
&mut self,
chs: DiskChs,
n: Option<u8>,
scope: RwSectorScope,
debug: bool,
) -> Result<ReadSectorResult, DiskImageError>;
fn scan_sector(&self, chs: DiskChs, n: Option<u8>) -> Result<ScanSectorResult, DiskImageError>;
fn write_sector(
&mut self,
chs: DiskChs,
n: Option<u8>,
write_data: &[u8],
scope: RwSectorScope,
write_deleted: bool,
debug: bool,
) -> Result<WriteSectorResult, DiskImageError>;
fn get_hash(&mut self) -> Digest;
fn read_all_sectors(&mut self, ch: DiskCh, n: u8, track_len: u8) -> Result<ReadTrackResult, DiskImageError>;
fn get_next_id(&self, chs: DiskChs) -> Option<DiskChsn>;
fn read_track(&mut self, overdump: Option<usize>) -> Result<ReadTrackResult, DiskImageError>;
fn read_track_raw(&mut self, overdump: Option<usize>) -> Result<ReadTrackResult, DiskImageError>;
fn has_weak_bits(&self) -> bool;
fn format(
&mut self,
standard: System34Standard,
format_buffer: Vec<DiskChsn>,
fill_pattern: &[u8],
gap3: usize,
) -> Result<(), DiskImageError>;
fn get_track_consistency(&self) -> Result<TrackConsistency, DiskImageError>;
fn get_track_stream(&self) -> Option<&TrackDataStream>;
}
pub type DiskTrack = Box<dyn Track + Send + Sync>;