infinite_rs/module/
block.rs

1//! Module block containing info relating to Kraken compression.
2
3use byteorder::{LE, ReadBytesExt};
4use std::io::BufRead;
5
6use crate::Result;
7use crate::common::errors::ModuleError;
8use crate::common::extensions::Enumerable;
9
10#[derive(Default, Debug)]
11/// Represents a module block entry containing information related to Kraken compression.
12/// This struct is used to determine how to read bytes in [`ModuleFileEntry`](`super::file::ModuleFileEntry`).
13pub(crate) struct ModuleBlockEntry {
14    /// Offset in bytes of compressed data inside the module (after [`file_data_offset`](`super::loader::ModuleFile::file_data_offset`) in the module).
15    pub(super) compressed_offset: u32,
16    /// Size in bytes of compressed data inside the module.
17    pub(super) compressed_size: u32,
18    /// Offset in bytes of decompressed data inside the decompression buffer.
19    pub(super) decompressed_offset: u32,
20    /// Size in bytes of the decompression buffer.
21    pub(super) decompressed_size: u32,
22    /// Boolean indicating if the block is compressed or not.
23    /// Tags can be made up of both compressed and decompressed blocks.
24    pub(super) is_compressed: bool,
25}
26
27impl Enumerable for ModuleBlockEntry {
28    fn read<R: BufRead>(&mut self, reader: &mut R) -> Result<()> {
29        self.compressed_offset = reader.read_u32::<LE>()?;
30        self.compressed_size = reader.read_u32::<LE>()?;
31        self.decompressed_offset = reader.read_u32::<LE>()?;
32        self.decompressed_size = reader.read_u32::<LE>()?;
33        let temp_compressed = reader.read_u32::<LE>()?;
34        if temp_compressed != 0 && temp_compressed != 1 {
35            return Err(ModuleError::IncorrectCompressedValue.into());
36        }
37        self.is_compressed = temp_compressed != 0;
38        Ok(())
39    }
40}