use hex;
use log::debug;
use serde::{Deserialize, Serialize};
use std::io::{Read, Seek};
use crate::parser::reader::ReadExt;
use crate::{error::Error, types::flags::*};
const MANIFEST_MAGIC: u32 = 0x44BEC00C;
#[derive(Debug, Clone, Serialize, Deserialize, Default)]
pub struct ManifestHeader {
pub header_size: i32,
pub data_size_uncompressed: i32,
pub data_size_compressed: i32,
pub sha1_hash: String,
pub stored_as: u8,
pub version: i32,
pub guid: String,
pub rolling_hash: i64,
pub hash_type: u32,
}
impl ManifestHeader {
pub fn read<R: Read + Seek>(mut rdr: R) -> Result<Self, Error> {
let magic = rdr.u32()?;
if magic != MANIFEST_MAGIC {
return Err(Error::Invalid("invalid manifest magic number".to_string()));
}
let header_size = rdr.i32()?;
debug!(" Header size from file: {}", header_size);
let data_size_uncompressed = rdr.i32()?;
let data_size_compressed = rdr.i32()?;
let mut hash = [0u8; 20];
rdr.read_exact(&mut hash)?;
debug!("Raw SHA-1 bytes from file: {:02x?}", hash);
let stored_as = rdr.u8()?;
let version = if header_size > 37 {
rdr.i32()?
} else {
0 };
let current_pos = rdr.stream_position()?;
if current_pos < header_size as u64 {
rdr.seek(std::io::SeekFrom::Start(header_size as u64))?;
}
Ok(Self {
header_size,
data_size_uncompressed,
data_size_compressed,
sha1_hash: hex::encode(hash),
stored_as,
version,
guid: String::new(), rolling_hash: 0, hash_type: 0, })
}
pub fn is_compressed(&self) -> bool {
self.stored_as & STORED_COMPRESSED != 0
}
pub fn is_encrypted(&self) -> bool {
self.stored_as & STORED_ENCRYPTED != 0
}
}