1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
use flate2::read::ZlibDecoder;
use log::{debug, error};
use std::convert::TryInto;
use std::io::Read;
#[derive(Default, Debug, Clone, PartialEq)]
pub struct Chunk {
header_version: u32,
header_size: u32,
compressed_size: u32,
pub guid: String,
pub hash: u64,
compressed: bool,
pub sha_hash: Option<Vec<u8>>,
pub hash_type: Option<u8>,
pub uncompressed_size: Option<u32>,
pub data: Vec<u8>,
}
impl Chunk {
pub fn from_vec(buffer: Vec<u8>) -> Option<Chunk> {
let mut position: usize = 0;
let magic = crate::api::utils::read_le(&buffer, &mut position);
if magic != 2986228386 {
error!("No header magic");
return None;
}
let mut res = Chunk {
header_version: crate::api::utils::read_le(&buffer, &mut position),
header_size: crate::api::utils::read_le(&buffer, &mut position),
compressed_size: crate::api::utils::read_le(&buffer, &mut position),
guid: format!(
"{:08x}{:08x}{:08x}{:08x}",
crate::api::utils::read_le(&buffer, &mut position),
crate::api::utils::read_le(&buffer, &mut position),
crate::api::utils::read_le(&buffer, &mut position),
crate::api::utils::read_le(&buffer, &mut position)
),
hash: crate::api::utils::read_le_64(&buffer, &mut position),
compressed: match buffer[position] {
0 => false,
_ => true,
},
sha_hash: None,
hash_type: None,
uncompressed_size: None,
data: vec![],
};
position += 1;
if res.header_version >= 2 {
position += 20;
res.sha_hash = Some(buffer[position - 20..position].try_into().unwrap());
res.hash_type = Some(buffer[position]);
position += 1;
}
if res.header_version >= 3 {
res.uncompressed_size = Some(crate::api::utils::read_le(&buffer, &mut position));
}
debug!("Got chunk: {:?}", res);
res.data = if res.compressed {
let mut z = ZlibDecoder::new(&buffer[position..]);
let mut data: Vec<u8> = Vec::new();
z.read_to_end(&mut data).unwrap();
data
} else {
buffer[position..].to_vec()
};
Some(res)
}
}