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