Skip to main content

xz_rs/stream/
header.rs

1use crate::decode::{Decode, DecodeError};
2use crate::encode::Encode;
3
4use super::{StreamDecodeError, StreamFlags};
5
6const MAGIC_BYTES_LEN: usize = 6;
7const MAGIC_BYTES: [u8; MAGIC_BYTES_LEN] = [0xFD, 0x37, 0x7A, 0x58, 0x5A, 0x00];
8
9#[derive(Debug, Clone)]
10pub struct StreamHeader {
11    pub flags: StreamFlags,
12}
13
14impl Encode for StreamHeader {
15    fn encoding(&self) -> Vec<u8> {
16        MAGIC_BYTES
17            .into_iter()
18            .chain(self.flags.encoding())
19            .chain(self.flags.crc_32().to_le_bytes())
20            .collect()
21    }
22}
23
24impl Decode for StreamHeader {
25    fn decode<R: std::io::Read>(src: &mut R) -> Result<Self, DecodeError> {
26        let err = |e| Err(DecodeError::from(e));
27        use StreamDecodeError::*;
28
29        let mut bytes = [0u8; 12];
30        src.read_exact(&mut bytes)?;
31
32        if bytes[..MAGIC_BYTES_LEN] != MAGIC_BYTES {
33            return err(InvalidHeader);
34        }
35
36        let flags = StreamFlags::try_from(&[bytes[MAGIC_BYTES_LEN], bytes[MAGIC_BYTES_LEN + 1]])?;
37
38        if flags.crc_32().to_le_bytes() != bytes[8..] {
39            return err(InvalidHeader);
40        }
41
42        Ok(Self { flags })
43    }
44}