--- /dev/null
+use std::io::{Read, Seek, SeekFrom};
+
+use binrw::{BinRead, binread};
+
+#[binread]
+#[br(little)]
+#[derive(Debug)]
+pub struct LegacyBin {
+ #[br(magic(0u8))]
+ version: Version,
+ #[br(temp)]
+ n_sources: u16,
+ member_size: u32,
+ #[br(count(n_sources), args { inner: (version,) })]
+ metadata: Vec<Metadata>,
+ #[br(count(n_sources), args { inner: metadata.as_slice() })]
+ data: Vec<Data>,
+}
+
+#[binread]
+#[br(little)]
+#[derive(Copy, Clone, Debug, PartialEq, Eq)]
+enum Version {
+ #[br(magic = 0xafu8)]
+ Vaf,
+ #[br(magic = 0xb0u8)]
+ Vb0,
+}
+
+#[binread]
+#[br(little, import(version: Version))]
+#[derive(Debug)]
+struct Metadata {
+ n_values: u32,
+ n_variables: u32,
+ data_offset: u32,
+ #[br(count(if version == Version::Vaf { 28 } else { 64 }))]
+ source_name: Vec<u8>,
+ #[br(if(version == Version::Vb0), temp)]
+ _x: u32,
+}
+
+#[derive(Debug)]
+struct Data {
+ variables: Vec<Variable>,
+}
+
+impl BinRead for Data {
+ type Args<'a> = &'a [Metadata];
+
+ fn read_options<R: Read + Seek>(
+ reader: &mut R,
+ endian: binrw::Endian,
+ metadata: Self::Args<'_>,
+ ) -> binrw::BinResult<Self> {
+ let mut variables = Vec::with_capacity(metadata.len());
+ for metadata in metadata {
+ reader.seek(SeekFrom::Start(metadata.data_offset as u64))?;
+ variables.push(Variable::read_options(
+ reader,
+ endian,
+ (metadata.n_values,),
+ )?);
+ }
+ Ok(Self { variables })
+ }
+}
+
+#[binread]
+#[br(little, import(n_values: u32))]
+#[derive(Debug)]
+struct Variable {
+ variable_name: [u8; 288],
+ #[br(count(n_values))]
+ values: Vec<f64>,
+}