}
*/
+trait ExtensionRecord where Self: Sized {
+ const SIZE: Option<u32>;
+ const COUNT: Option<u32>;
+ const NAME: &'static str;
+ fn parse(ext: &Extension, endian: Endian) -> Result<Self, Error>;
+}
+
+pub struct IntegerInfo {
+ version: (i32, i32, i32),
+ machine_code: i32,
+ floating_point_rep: i32,
+ compression_code: i32,
+ endianness: i32,
+ character_code: i32,
+}
+
+impl ExtensionRecord for IntegerInfo {
+ const SIZE: Option<u32> = Some(4);
+ const COUNT: Option<u32> = Some(8);
+ const NAME: &'static str = "integer record";
+
+ fn parse(ext: &Extension, endian: Endian) -> Result<Self, Error>{
+ ext.check_size::<Self>()?;
+
+ let mut input = &ext.data[..];
+ let data: Vec<i32> = (0..8)
+ .map(|_| endian.parse(read_bytes(&mut input).unwrap()))
+ .collect();
+ Ok(IntegerInfo {
+ version: (data[0], data[1], data[2]),
+ machine_code: data[3],
+ floating_point_rep: data[4],
+ compression_code: data[5],
+ endianness: data[6],
+ character_code: data[7]
+ })
+ }
+}
+
+pub struct FloatInfo {
+ sysmis: f64,
+ highest: f64,
+ lowest: f64,
+}
+
+impl ExtensionRecord for FloatInfo {
+ const SIZE: Option<u32> = Some(8);
+ const COUNT: Option<u32> = Some(3);
+ const NAME: &'static str = "floating point record";
+
+ fn parse(ext: &Extension, endian: Endian) -> Result<Self, Error>{
+ ext.check_size::<Self>()?;
+
+ let mut input = &ext.data[..];
+ let data: Vec<f64> = (0..3)
+ .map(|_| endian.parse(read_bytes(&mut input).unwrap()))
+ .collect();
+ Ok(FloatInfo {
+ sysmis: data[0],
+ highest: data[1],
+ lowest: data[2],
+ })
+ }
+}
+
pub struct Extension {
/// Offset from the start of the file to the start of the record.
pub offset: u64,
*/
impl Extension {
+ fn check_size<E: ExtensionRecord>(&self) -> Result<(), Error> {
+ if let Some(expected_size) = E::SIZE {
+ if self.size != expected_size {
+ return Err(Error::BadRecordSize {
+ offset: self.offset,
+ record: E::NAME.into(),
+ size: self.size,
+ expected_size,
+ });
+ }
+ }
+ if let Some(expected_count) = E::COUNT {
+ if self.count != expected_count {
+ return Err(Error::BadRecordCount {
+ offset: self.offset,
+ record: E::NAME.into(),
+ count: self.count,
+ expected_count,
+ });
+ }
+ }
+ Ok(())
+ }
+
fn read<R: Read + Seek>(r: &mut R, endian: Endian) -> Result<Extension, Error> {
let subtype = endian.parse(read_bytes(r)?);
let offset = r.stream_position()?;
}
impl ZBlock {
- fn read<R: Read + Seek>(
- r: &mut R,
- endian: Endian,
- ) -> Result<ZBlock, Error> {
+ fn read<R: Read + Seek>(r: &mut R, endian: Endian) -> Result<ZBlock, Error> {
Ok(ZBlock {
uncompressed_ofs: endian.parse(read_bytes(r)?),
compressed_ofs: endian.parse(read_bytes(r)?),
});
}
let blocks = (0..n_blocks)
- .map(|_| ZBlock::read(reader, endian))
- .collect::<Result<Vec<_>, _>>()?;
+ .map(|_| ZBlock::read(reader, endian))
+ .collect::<Result<Vec<_>, _>>()?;
reader.seek(SeekFrom::Start(start_offset))?;
Ok(Some(ZTrailer {
offset: ztrailer_ofs,