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}