pub mod system34;
use crate::{
bitstream::TrackDataStream,
chs::DiskChsn,
structure_parsers::system34::{System34Element, System34Marker},
};
use bit_vec::BitVec;
#[derive(Default)]
pub struct DiskStructureMetadata {
pub items: Vec<DiskStructureMetadataItem>,
}
impl DiskStructureMetadata {
pub fn new(items: Vec<DiskStructureMetadataItem>) -> Self {
DiskStructureMetadata { items }
}
pub fn add_item(&mut self, item: DiskStructureMetadataItem) {
self.items.push(item);
}
pub fn item_at(&self, index: usize) -> Option<(&DiskStructureMetadataItem, u32)> {
let mut ref_stack = Vec::new();
let mut match_ct = 0;
for item in &self.items {
if item.start <= index && item.end >= index {
ref_stack.push(item);
match_ct += 1;
}
}
if ref_stack.is_empty() {
None
}
else {
ref_stack.sort_by(|a, b| a.start.cmp(&b.start));
Some((ref_stack.pop()?, match_ct))
}
}
pub fn sector_ct(&self) -> u8 {
let mut sector_ct = 0;
for item in &self.items {
if item.elem_type.is_sector() {
sector_ct += 1;
}
}
sector_ct
}
pub fn get_sector_ids(&self) -> Vec<DiskChsn> {
let mut sector_ids = Vec::new();
for item in &self.items {
if let DiskStructureElement::System34(System34Element::SectorHeader { chsn, .. }) = item.elem_type {
sector_ids.push(chsn);
}
}
sector_ids
}
pub fn data_ranges(&self) -> Vec<(usize, usize)> {
let mut data_ranges = Vec::new();
for item in &self.items {
if let DiskStructureElement::System34(System34Element::Data { .. }) = item.elem_type {
data_ranges.push((item.start, item.end));
}
}
data_ranges
}
}
#[derive(Copy, Clone, Debug)]
pub struct DiskStructureMarkerItem {
pub(crate) elem_type: DiskStructureMarker,
pub(crate) start: usize,
}
#[derive(Copy, Clone, Debug)]
pub struct DiskStructureMetadataItem {
pub(crate) elem_type: DiskStructureElement,
pub(crate) start: usize,
pub(crate) end: usize,
pub(crate) chsn: Option<DiskChsn>,
pub(crate) _crc: Option<DiskStructureCrc>,
}
#[derive(Copy, Clone, Debug)]
pub struct DiskStructureCrc {
stored: u16,
calculated: u16,
}
impl DiskStructureCrc {
pub fn valid(&self) -> bool {
self.stored == self.calculated
}
}
#[derive(Copy, Clone, Debug)]
pub enum DiskStructureMarker {
System34(System34Marker),
Placeholder,
}
#[derive(Copy, Clone, PartialEq, Eq, Hash, Debug)]
pub enum DiskStructureGenericElement {
NoElement,
Marker,
SectorHeader,
SectorBadHeader,
SectorData,
SectorDeletedData,
SectorBadData,
SectorBadDeletedData,
}
#[derive(Copy, Clone, Debug)]
pub enum DiskStructureElement {
System34(System34Element),
Placeholder,
}
impl From<DiskStructureElement> for DiskStructureGenericElement {
fn from(elem: DiskStructureElement) -> Self {
match elem {
DiskStructureElement::System34(sys34elem) => sys34elem.into(),
_ => DiskStructureGenericElement::NoElement,
}
}
}
impl DiskStructureElement {
pub fn is_sector(&self) -> bool {
match self {
DiskStructureElement::System34(elem) => elem.is_sector(),
_ => false,
}
}
}
pub trait DiskStructureParser {
fn find_data_pattern(track: &TrackDataStream, pattern: &[u8], offset: usize) -> Option<usize>;
fn find_next_marker(track: &TrackDataStream, offset: usize) -> Option<(DiskStructureMarker, usize)>;
fn find_marker(
track: &TrackDataStream,
marker: DiskStructureMarker,
offset: usize,
limit: Option<usize>,
) -> Option<(usize, u16)>;
fn find_element(track: &TrackDataStream, element: DiskStructureElement, offset: usize) -> Option<usize>;
fn scan_track_markers(track: &TrackDataStream) -> Vec<DiskStructureMarkerItem>;
fn scan_track_metadata(
track: &mut TrackDataStream,
markers: Vec<DiskStructureMarkerItem>,
) -> Vec<DiskStructureMetadataItem>;
fn create_clock_map(markers: &[DiskStructureMarkerItem], clock_map: &mut BitVec);
fn crc16(track: &mut TrackDataStream, bit_index: usize, end: usize) -> (u16, u16);
}