@@ -8,14 +8,33 @@ use brotli::enc::StandardAlloc; // Re-exported from alloc_stdlib::StandardAlloc
88use brotli:: { self , BrotliDecompressStream , BrotliResult , BrotliState } ;
99use wasm_bindgen:: prelude:: * ;
1010
11+ /// Returned by every successful (de)compression.
12+ //
13+ // Use `getter_with_clone` because `buf` does not implement `Copy`.
14+ #[ wasm_bindgen( getter_with_clone) ]
15+ pub struct BrotliStreamResult {
16+ /// Result code.
17+ ///
18+ /// See [`BrotliStreamResultCode`] for available values.
19+ ///
20+ /// When error, the error code is not passed here but rather goes to `Err`.
21+ pub code : BrotliStreamResultCode ,
22+ /// Output buffer
23+ pub buf : Box < [ u8 ] > ,
24+ /// Consumed bytes of the input buffer
25+ pub input_offset : usize ,
26+ }
27+
1128#[ wasm_bindgen]
12- #[ repr( i32 ) ]
13- pub enum BrotliStreamResult {
14- /// The stream is just initialized and no input is provided currently.
15- /// `BrotliResult` uses `ResultFailure = 0`, but as we will convert `ResultFailure` to a negative actual error code,
16- /// 0 is reused as no input currently.
17- /// As for Brotli compressing, since offical API does not provide a way to retrieve a detailed error code, -1 is used.
18- Init = 0 ,
29+ /// Same as [`brotli::BrotliResult`] except [`brotli::BrotliResult::ResultFailure`].
30+ ///
31+ /// Always `> 0`.
32+ ///
33+ /// `ResultFailure` is removed
34+ /// because we will convert the failure to an actual negative error code (if available) and pass it elsewhere.
35+ #[ repr( usize ) ]
36+ #[ derive( Copy , Clone ) ]
37+ pub enum BrotliStreamResultCode {
1938 ResultSuccess = 1 ,
2039 NeedsMoreInput = 2 ,
2140 NeedsMoreOutput = 3 ,
@@ -24,9 +43,7 @@ pub enum BrotliStreamResult {
2443#[ wasm_bindgen]
2544pub struct CompressStream {
2645 state : BrotliEncoderStateStruct < StandardAlloc > ,
27- result : i32 ,
2846 total_out : usize ,
29- last_input_offset : usize ,
3047}
3148
3249impl Drop for CompressStream {
@@ -54,17 +71,15 @@ impl CompressStream {
5471 }
5572 Self {
5673 state,
57- result : BrotliStreamResult :: Init as i32 ,
5874 total_out : 0 ,
59- last_input_offset : 0 ,
6075 }
6176 }
6277
6378 pub fn compress (
6479 & mut self ,
6580 input_opt : Option < Box < [ u8 ] > > ,
6681 output_size : usize ,
67- ) -> Result < Box < [ u8 ] > , JsValue > {
82+ ) -> Result < BrotliStreamResult , JsError > {
6883 let mut nop_callback = |_data : & mut brotli:: interface:: PredictionModeContextMap <
6984 brotli:: interface:: InputReferenceMut ,
7085 > ,
@@ -97,22 +112,22 @@ impl CompressStream {
97112 if ret != 0 {
98113 if available_in == 0 {
99114 output. truncate ( output_offset) ;
100- self . result = BrotliStreamResult :: NeedsMoreInput as i32 ;
101- self . last_input_offset = input. len ( ) ;
102- Ok ( output. into_boxed_slice ( ) )
115+ Ok ( BrotliStreamResult {
116+ code : BrotliStreamResultCode :: NeedsMoreInput ,
117+ buf : output. into_boxed_slice ( ) ,
118+ input_offset,
119+ } )
103120 } else if available_out == 0 {
104- self . result = BrotliStreamResult :: NeedsMoreOutput as i32 ;
105- self . last_input_offset = input_offset;
106- Ok ( output. into_boxed_slice ( ) )
121+ Ok ( BrotliStreamResult {
122+ code : BrotliStreamResultCode :: NeedsMoreOutput ,
123+ buf : output. into_boxed_slice ( ) ,
124+ input_offset,
125+ } )
107126 } else {
108- self . result = -1 ;
109- self . last_input_offset = 0 ;
110- Err ( JsValue :: from_str ( "Unexpected Brotli streaming compress: both available_in & available_out are not 0 after a successful processing" ) )
127+ Err ( JsError :: new ( "Unexpected Brotli streaming compress: both available_in & available_out are not 0 after a successful processing" ) )
111128 }
112129 } else {
113- self . result = -1 ;
114- self . last_input_offset = 0 ;
115- Err ( JsValue :: from_str (
130+ Err ( JsError :: new (
116131 "Brotli streaming compress failed: When processing" ,
117132 ) )
118133 }
@@ -135,43 +150,38 @@ impl CompressStream {
135150 & mut nop_callback,
136151 ) ;
137152 if ret == 0 {
138- self . result = -1 ;
139- return Err ( JsValue :: from_str (
153+ return Err ( JsError :: new (
140154 "Brotli streaming compress failed: When finishing" ,
141155 ) ) ;
142156 }
143157 }
144- self . result = if available_out == 0 {
145- BrotliStreamResult :: NeedsMoreOutput as i32
158+ if available_out == 0 {
159+ Ok ( BrotliStreamResult {
160+ code : BrotliStreamResultCode :: NeedsMoreOutput ,
161+ buf : output. into_boxed_slice ( ) ,
162+ input_offset,
163+ } )
146164 } else {
147165 output. truncate ( output_offset) ;
148- BrotliStreamResult :: ResultSuccess as i32
149- } ;
150- self . last_input_offset = 0 ;
151- Ok ( output. into_boxed_slice ( ) )
166+ Ok ( BrotliStreamResult {
167+ code : BrotliStreamResultCode :: ResultSuccess ,
168+ buf : output. into_boxed_slice ( ) ,
169+ input_offset,
170+ } )
171+ }
152172 }
153173 }
154174 }
155175
156176 pub fn total_out ( & self ) -> usize {
157177 self . total_out
158178 }
159-
160- pub fn result ( & self ) -> i32 {
161- self . result
162- }
163-
164- pub fn last_input_offset ( & self ) -> usize {
165- self . last_input_offset
166- }
167179}
168180
169181#[ wasm_bindgen]
170182pub struct DecompressStream {
171183 state : BrotliState < StandardAlloc , StandardAlloc , StandardAlloc > ,
172- result : i32 ,
173184 total_out : usize ,
174- last_input_offset : usize ,
175185}
176186
177187#[ wasm_bindgen]
@@ -183,17 +193,15 @@ impl DecompressStream {
183193 let alloc = StandardAlloc :: default ( ) ;
184194 Self {
185195 state : BrotliState :: new ( alloc, alloc, alloc) ,
186- result : BrotliStreamResult :: Init as i32 ,
187196 total_out : 0 ,
188- last_input_offset : 0 ,
189197 }
190198 }
191199
192200 pub fn decompress (
193201 & mut self ,
194202 input : Box < [ u8 ] > ,
195203 output_size : usize ,
196- ) -> Result < Box < [ u8 ] > , JsValue > {
204+ ) -> Result < BrotliStreamResult , JsError > {
197205 let mut output = vec ! [ 0 ; output_size] ;
198206 let mut available_in = input. len ( ) ;
199207 let mut input_offset = 0 ;
@@ -211,42 +219,37 @@ impl DecompressStream {
211219 ) {
212220 BrotliResult :: ResultFailure => {
213221 // It should be a negative error code
214- self . result = self . state . error_code as i32 ;
215- self . last_input_offset = 0 ;
216- Err ( JsValue :: from_str ( & format ! (
222+ let err_code = self . state . error_code as i32 ;
223+ Err ( JsError :: new ( & format ! (
217224 "Brotli streaming decompress failed: Error code {}" ,
218- self . result
225+ err_code
219226 ) ) )
220227 }
221- BrotliResult :: NeedsMoreOutput => {
222- self . result = BrotliStreamResult :: NeedsMoreOutput as i32 ;
223- self . last_input_offset = input_offset ;
224- Ok ( output . into_boxed_slice ( ) )
225- }
228+ BrotliResult :: NeedsMoreOutput => Ok ( BrotliStreamResult {
229+ code : BrotliStreamResultCode :: NeedsMoreOutput ,
230+ buf : output . into_boxed_slice ( ) ,
231+ input_offset ,
232+ } ) ,
226233 BrotliResult :: ResultSuccess => {
227234 output. truncate ( output_offset) ;
228- self . result = BrotliStreamResult :: ResultSuccess as i32 ;
229- self . last_input_offset = input. len ( ) ;
230- Ok ( output. into_boxed_slice ( ) )
235+ Ok ( BrotliStreamResult {
236+ code : BrotliStreamResultCode :: ResultSuccess ,
237+ buf : output. into_boxed_slice ( ) ,
238+ input_offset,
239+ } )
231240 }
232241 BrotliResult :: NeedsMoreInput => {
233242 output. truncate ( output_offset) ;
234- self . result = BrotliStreamResult :: NeedsMoreInput as i32 ;
235- self . last_input_offset = input. len ( ) ;
236- Ok ( output. into_boxed_slice ( ) )
243+ Ok ( BrotliStreamResult {
244+ code : BrotliStreamResultCode :: NeedsMoreInput ,
245+ buf : output. into_boxed_slice ( ) ,
246+ input_offset,
247+ } )
237248 }
238249 }
239250 }
240251
241252 pub fn total_out ( & self ) -> usize {
242253 self . total_out
243254 }
244-
245- pub fn result ( & self ) -> i32 {
246- self . result
247- }
248-
249- pub fn last_input_offset ( & self ) -> usize {
250- self . last_input_offset
251- }
252255}
0 commit comments