Skip to main content

steamkit/util/lzma/
i_coder.rs

1//! Coder traits from the 7-Zip LZMA SDK (`ICoder`).
2
3use crate::error::SteamError;
4
5/// The exception that is thrown when the value of an argument is outside the allowable range.
6#[derive(Debug, Clone, Copy, PartialEq, Eq, thiserror::Error)]
7#[error("Invalid Parameter")]
8pub struct InvalidParamException;
9
10impl From<InvalidParamException> for SteamError {
11    fn from(value: InvalidParamException) -> Self {
12        SteamError::InvalidArgument(value.to_string())
13    }
14}
15
16/// Callback progress.
17pub trait ICodeProgress {
18    /// Reports progress. Either size is -1 if unknown.
19    fn set_progress(&mut self, in_size: i64, out_size: i64);
20}
21
22/// Something that compresses an input buffer into an output buffer.
23pub trait ICoder {
24    /// Compresses `in_stream` and appends the result to `out_stream`.
25    ///
26    /// `in_size` and `out_size` are -1 if unknown.
27    fn code(
28        &mut self,
29        in_stream: Vec<u8>,
30        out_stream: &mut Vec<u8>,
31        in_size: i64,
32        out_size: i64,
33        progress: Option<&mut dyn ICodeProgress>,
34    ) -> Result<(), SteamError>;
35}
36
37/// Coder property identifiers.
38#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
39pub enum CoderPropID {
40    /// Default property.
41    DefaultProp = 0,
42    /// Dictionary size.
43    DictionarySize,
44    /// Memory size for PPM*.
45    UsedMemorySize,
46    /// Order for PPM methods.
47    Order,
48    /// Block size.
49    BlockSize,
50    /// Number of position state bits for LZMA (0 <= x <= 4).
51    PosStateBits,
52    /// Number of literal context bits for LZMA (0 <= x <= 8).
53    LitContextBits,
54    /// Number of literal position bits for LZMA (0 <= x <= 4).
55    LitPosBits,
56    /// Number of fast bytes for LZ*.
57    NumFastBytes,
58    /// Match finder. LZMA: "BT2", "BT4" or "BT4B".
59    MatchFinder,
60    /// Number of match finder cycles.
61    MatchFinderCycles,
62    /// Number of passes.
63    NumPasses,
64    /// Algorithm number.
65    Algorithm,
66    /// Number of threads.
67    NumThreads,
68    /// Write an end marker.
69    EndMarker,
70}
71
72/// A coder property value.
73#[derive(Debug, Clone, PartialEq, Eq)]
74pub enum CoderProperty {
75    /// A 32-bit signed integer property.
76    Int32(i32),
77    /// A 32-bit unsigned integer property.
78    UInt32(u32),
79    /// A boolean property.
80    Boolean(bool),
81    /// A string property.
82    String(String),
83}
84
85impl CoderProperty {
86    /// Returns the value as an `i32`, if it is an integer property.
87    pub fn as_i32(&self) -> Option<i32> {
88        match self {
89            CoderProperty::Int32(v) => Some(*v),
90            CoderProperty::UInt32(v) => Some(*v as i32),
91            _ => None,
92        }
93    }
94
95    /// Returns the value as a `bool`, if it is a boolean property.
96    pub fn as_bool(&self) -> Option<bool> {
97        match self {
98            CoderProperty::Boolean(v) => Some(*v),
99            _ => None,
100        }
101    }
102
103    /// Returns the value as a `&str`, if it is a string property.
104    pub fn as_str(&self) -> Option<&str> {
105        match self {
106            CoderProperty::String(v) => Some(v.as_str()),
107            _ => None,
108        }
109    }
110}
111
112/// Sets coder properties.
113pub trait ISetCoderProperties {
114    /// Sets the coder properties.
115    ///
116    /// Fails with [`InvalidParamException`] when a property has the wrong
117    /// type or an out-of-range value.
118    fn set_coder_properties(
119        &mut self,
120        prop_ids: &[CoderPropID],
121        properties: &[CoderProperty],
122    ) -> Result<(), InvalidParamException>;
123}
124
125/// Writes coder properties.
126pub trait IWriteCoderProperties {
127    /// Writes the coder properties (the 5 byte LZMA header) to `out_stream`.
128    fn write_coder_properties(&mut self, out_stream: &mut Vec<u8>);
129}