zstd/bulk/
decompressor.rs1use crate::map_error_code;
2
3#[cfg(feature = "experimental")]
4use std::convert::TryInto;
5use std::io;
6use zstd_safe;
7
8#[derive(Default)]
12pub struct Decompressor<'a> {
13 context: zstd_safe::DCtx<'a>,
14}
15
16impl Decompressor<'static> {
17 pub fn new() -> io::Result<Self> {
19 Self::with_dictionary(&[])
20 }
21
22 pub fn with_dictionary(dictionary: &[u8]) -> io::Result<Self> {
24 let mut decompressor = Self::default();
25
26 decompressor.set_dictionary(dictionary)?;
27
28 Ok(decompressor)
29 }
30}
31
32impl<'a> Decompressor<'a> {
33 pub fn with_prepared_dictionary<'b>(
38 dictionary: &'a crate::dict::DecoderDictionary<'b>,
39 ) -> io::Result<Self>
40 where
41 'b: 'a,
42 {
43 let mut decompressor = Self::default();
44
45 decompressor.set_prepared_dictionary(dictionary)?;
46
47 Ok(decompressor)
48 }
49
50 pub fn set_dictionary(&mut self, dictionary: &[u8]) -> io::Result<()> {
57 self.context
58 .load_dictionary(dictionary)
59 .map_err(map_error_code)?;
60
61 Ok(())
62 }
63
64 pub fn set_prepared_dictionary<'b>(
69 &mut self,
70 dictionary: &'a crate::dict::DecoderDictionary<'b>,
71 ) -> io::Result<()>
72 where
73 'b: 'a,
74 {
75 self.context
76 .ref_ddict(dictionary.as_ddict())
77 .map_err(map_error_code)?;
78
79 Ok(())
80 }
81
82 pub fn decompress_to_buffer<C: zstd_safe::WriteBuf + ?Sized>(
87 &mut self,
88 source: &[u8],
89 destination: &mut C,
90 ) -> io::Result<usize> {
91 self.context
92 .decompress(destination, source)
93 .map_err(map_error_code)
94 }
95
96 pub fn decompress(
101 &mut self,
102 data: &[u8],
103 capacity: usize,
104 ) -> io::Result<Vec<u8>> {
105 let capacity =
106 Self::upper_bound(data).unwrap_or(capacity).min(capacity);
107 let mut buffer = Vec::with_capacity(capacity);
108 self.decompress_to_buffer(data, &mut buffer)?;
109 Ok(buffer)
110 }
111
112 pub fn set_parameter(
114 &mut self,
115 parameter: zstd_safe::DParameter,
116 ) -> io::Result<()> {
117 self.context
118 .set_parameter(parameter)
119 .map_err(map_error_code)?;
120 Ok(())
121 }
122
123 crate::decoder_parameters!();
124
125 pub fn upper_bound(_data: &[u8]) -> Option<usize> {
135 #[cfg(feature = "experimental")]
136 {
137 let bound = zstd_safe::decompress_bound(_data).ok()?;
138 bound.try_into().ok()
139 }
140 #[cfg(not(feature = "experimental"))]
141 {
142 None
143 }
144 }
145}
146
147fn _assert_traits() {
148 fn _assert_send<T: Send>(_: T) {}
149
150 _assert_send(Decompressor::new());
151}