use super::daf::{Daf, Summary};
use std::path::Path;
pub struct SegmentMeta {
pub init: f64,
pub intlen: f64,
pub rsize: usize,
pub ncoeff: usize,
pub n_records: usize,
pub records: Vec<f64>,
}
pub fn read_type2_segment(
file_data: &[u8],
daf: &Daf,
summary: &Summary,
) -> anyhow::Result<SegmentMeta> {
let end = summary.end_word;
let n_records = daf.read_f64_at_word(file_data, end) as usize;
let rsize = daf.read_f64_at_word(file_data, end - 1) as usize;
let intlen = daf.read_f64_at_word(file_data, end - 2);
let init = daf.read_f64_at_word(file_data, end - 3);
if rsize < 5 || rsize > 200 {
anyhow::bail!("Implausible rsize={} for SPK Type 2 segment", rsize);
}
let ncoeff = (rsize - 2) / 3;
if 2 + 3 * ncoeff != rsize {
anyhow::bail!(
"rsize={} is not 2 + 3k for any k (ncoeff would be {})",
rsize,
ncoeff
);
}
if n_records == 0 || n_records > 10_000_000 {
anyhow::bail!("Implausible n_records={}", n_records);
}
let total_doubles = n_records * rsize;
let mut records = Vec::with_capacity(total_doubles);
let data_start_word = summary.start_word;
for i in 0..total_doubles {
let word = data_start_word + i;
records.push(daf.read_f64_at_word(file_data, word));
}
Ok(SegmentMeta {
init,
intlen,
rsize,
ncoeff,
n_records,
records,
})
}
pub fn write_binary(meta: &SegmentMeta, path: &Path) -> anyhow::Result<()> {
let mut buf = Vec::with_capacity(meta.records.len() * 8);
for &val in &meta.records {
buf.extend_from_slice(&val.to_le_bytes());
}
std::fs::write(path, &buf)?;
Ok(())
}