D88FileIO/
sector.rs

1use std::io::{BufReader, Read};
2use std::io::{Seek, SeekFrom};
3use std::mem;
4
5use crate::format::D88_SectorHdr;
6///
7
8#[derive(Default, Debug)]
9pub struct Sector {
10    pub offset: u64,
11    pub header: D88_SectorHdr,
12    pub data: Vec<u8>,
13}
14impl Sector {
15    /// Read Sector
16    ///
17    /// # Argument
18    ///
19    ///   * `reader` &mut BufReader<std::fs::File>
20    ///
21    /// # Return
22    ///
23    ///   * Ok(usize)  Sector Data Size (with Sector Header)
24    ///   * Err(())    
25    ///
26    #[allow(clippy::result_unit_err)]
27    pub fn preset(
28        &mut self,
29        reader: &mut BufReader<std::fs::File>,
30        offset: u64,
31    ) -> Result<u64, ()> {
32        if offset == 0 {
33            return Err(());
34        }
35
36        if reader.seek(SeekFrom::Start(offset)).is_err() {
37            return Err(());
38        }
39
40        let mut buf: [u8; mem::size_of::<D88_SectorHdr>()] = [0; mem::size_of::<D88_SectorHdr>()]; // Header Buffer
41        if let Ok(read_size) = reader.read(&mut buf) {
42            if read_size != mem::size_of::<D88_SectorHdr>() {
43                return Err(());
44            }
45
46            let d88_sector_header;
47            unsafe {
48                d88_sector_header =
49                    mem::transmute::<[u8; mem::size_of::<D88_SectorHdr>()], D88_SectorHdr>(buf);
50            }
51            let sector_offset = offset + mem::size_of::<D88_SectorHdr>() as u64;
52
53            let ret_sector_size =
54                mem::size_of::<D88_SectorHdr>() + ((128 << d88_sector_header.sector_size) as usize);
55
56            let mut sector_data: Vec<u8> = vec![0; d88_sector_header.size_of_data.into()];
57            if reader.seek(SeekFrom::Start(sector_offset)).is_err() {
58                return Err(());
59            }
60            if reader.read(&mut sector_data).is_err() {
61                return Err(());
62            }
63
64            //
65            self.offset = sector_offset;
66            self.header = d88_sector_header;
67            self.data = sector_data;
68
69            Ok(ret_sector_size as u64)
70        } else {
71            Err(())
72        }
73    }
74
75    ///
76    ///
77    pub fn get_track(&self) -> String {
78        format!("Track({})", self.header.track)
79    }
80
81    pub fn get_side(&self) -> String {
82        format!("Side({})", self.header.side)
83    }
84
85    pub fn get_sector(&self) -> String {
86        format!("Sector({})", self.header.sector)
87    }
88
89    pub fn get_sector_size(&self) -> String {
90        format!("Size({} byte/sec)", 128 << (self.header.sector_size))
91    }
92
93    pub fn get_num_of_sector(&self) -> String {
94        format!("NumOfSector({} sec/track)", self.header.number_of_sec)
95    }
96
97    pub fn get_status(&self) -> String {
98        format!(
99            "Status({})",
100            match self.header.status {
101                0x00 => "OK",           // 正常
102                0x10 => "DELETED",      // 削除済みデータ
103                0xa0 => "ID CRC Err",   // ID CRC エラー
104                0xb0 => "Data CRC Err", // データ CRC エラー
105                0xe0 => "No Addr Mark", // アドレスマークなし
106                0xf0 => "No Data Mark", // データマークなし
107                _ => "??",
108            }
109        )
110    }
111
112    pub fn get_density(&self) -> String {
113        format!(
114            "Density({})",
115            match self.header.density {
116                0x00 => "D",  // 倍密度 // dencityの仕様がよく分からない。
117                0x40 => "S",  // 単密度
118                0x01 => "HD", // 高密度
119                _ => "??",
120            } //"Density({:02x}h), ",
121              //self.header.density
122        )
123    }
124
125    pub fn get_mark(&self) -> String {
126        format!(
127            "Mark({})",
128            match self.header.deleted_mark {
129                0x00 => "NORMAL",
130                0x10 => "DELETED",
131                _ => "??",
132            }
133        )
134    }
135
136    pub fn get_data_size(&self) -> String {
137        format!("DataSize({} byte), ", self.header.size_of_data)
138    }
139}