/rust/registry/src/index.crates.io-1949cf8c6b5b557f/lzma-rs-0.2.0/src/xz/header.rs
Line | Count | Source |
1 | | //! XZ header. |
2 | | |
3 | | use crate::decode::util; |
4 | | use crate::error; |
5 | | use crate::xz::StreamFlags; |
6 | | use byteorder::{BigEndian, LittleEndian, ReadBytesExt}; |
7 | | use crc::crc32::{self, Hasher32}; |
8 | | |
9 | | /// File format magic header signature, see sect. 2.1.1.1. |
10 | | pub(crate) const XZ_MAGIC: &[u8] = &[0xFD, 0x37, 0x7A, 0x58, 0x5A, 0x00]; |
11 | | |
12 | | /// Stream Header, see sect. 2.1.1. |
13 | | #[derive(Clone, Copy, Debug)] |
14 | | pub(crate) struct StreamHeader { |
15 | | pub(crate) stream_flags: StreamFlags, |
16 | | } |
17 | | |
18 | | impl StreamHeader { |
19 | | /// Parse a Stream Header from a buffered reader. |
20 | 0 | pub(crate) fn parse<BR>(input: &mut BR) -> error::Result<Self> |
21 | 0 | where |
22 | 0 | BR: std::io::BufRead, |
23 | | { |
24 | 0 | if !util::read_tag(input, XZ_MAGIC)? { |
25 | 0 | return Err(error::Error::XzError(format!( |
26 | 0 | "Invalid XZ magic, expected {:?}", |
27 | 0 | XZ_MAGIC |
28 | 0 | ))); |
29 | 0 | } |
30 | | |
31 | 0 | let (flags, digested) = { |
32 | 0 | let mut digest = crc32::Digest::new(crc32::IEEE); |
33 | 0 | let mut digest_rd = util::HasherRead::new(input, &mut digest); |
34 | 0 | let value = digest_rd.read_u16::<BigEndian>()?; |
35 | 0 | (value, digest.sum32()) |
36 | | }; |
37 | | |
38 | 0 | let crc32 = input.read_u32::<LittleEndian>()?; |
39 | 0 | if crc32 != digested { |
40 | 0 | return Err(error::Error::XzError(format!( |
41 | 0 | "Invalid header CRC32: expected 0x{:08x} but got 0x{:08x}", |
42 | 0 | crc32, digested |
43 | 0 | ))); |
44 | 0 | } |
45 | | |
46 | 0 | let stream_flags = StreamFlags::parse(flags)?; |
47 | 0 | let header = Self { stream_flags }; |
48 | | |
49 | | lzma_info!("XZ check method: {:?}", header.stream_flags.check_method); |
50 | 0 | Ok(header) |
51 | 0 | } |
52 | | } |