@@ -8,14 +8,33 @@ use brotli::enc::StandardAlloc; // Re-exported from alloc_stdlib::StandardAlloc
8
8
use brotli:: { self , BrotliDecompressStream , BrotliResult , BrotliState } ;
9
9
use wasm_bindgen:: prelude:: * ;
10
10
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
+
11
28
#[ 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 {
19
38
ResultSuccess = 1 ,
20
39
NeedsMoreInput = 2 ,
21
40
NeedsMoreOutput = 3 ,
@@ -24,9 +43,7 @@ pub enum BrotliStreamResult {
24
43
#[ wasm_bindgen]
25
44
pub struct CompressStream {
26
45
state : BrotliEncoderStateStruct < StandardAlloc > ,
27
- result : i32 ,
28
46
total_out : usize ,
29
- last_input_offset : usize ,
30
47
}
31
48
32
49
impl Drop for CompressStream {
@@ -54,17 +71,15 @@ impl CompressStream {
54
71
}
55
72
Self {
56
73
state,
57
- result : BrotliStreamResult :: Init as i32 ,
58
74
total_out : 0 ,
59
- last_input_offset : 0 ,
60
75
}
61
76
}
62
77
63
78
pub fn compress (
64
79
& mut self ,
65
80
input_opt : Option < Box < [ u8 ] > > ,
66
81
output_size : usize ,
67
- ) -> Result < Box < [ u8 ] > , JsValue > {
82
+ ) -> Result < BrotliStreamResult , JsError > {
68
83
let mut nop_callback = |_data : & mut brotli:: interface:: PredictionModeContextMap <
69
84
brotli:: interface:: InputReferenceMut ,
70
85
> ,
@@ -97,22 +112,22 @@ impl CompressStream {
97
112
if ret != 0 {
98
113
if available_in == 0 {
99
114
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
+ } )
103
120
} 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
+ } )
107
126
} 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" ) )
111
128
}
112
129
} else {
113
- self . result = -1 ;
114
- self . last_input_offset = 0 ;
115
- Err ( JsValue :: from_str (
130
+ Err ( JsError :: new (
116
131
"Brotli streaming compress failed: When processing" ,
117
132
) )
118
133
}
@@ -135,43 +150,38 @@ impl CompressStream {
135
150
& mut nop_callback,
136
151
) ;
137
152
if ret == 0 {
138
- self . result = -1 ;
139
- return Err ( JsValue :: from_str (
153
+ return Err ( JsError :: new (
140
154
"Brotli streaming compress failed: When finishing" ,
141
155
) ) ;
142
156
}
143
157
}
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
+ } )
146
164
} else {
147
165
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
+ }
152
172
}
153
173
}
154
174
}
155
175
156
176
pub fn total_out ( & self ) -> usize {
157
177
self . total_out
158
178
}
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
- }
167
179
}
168
180
169
181
#[ wasm_bindgen]
170
182
pub struct DecompressStream {
171
183
state : BrotliState < StandardAlloc , StandardAlloc , StandardAlloc > ,
172
- result : i32 ,
173
184
total_out : usize ,
174
- last_input_offset : usize ,
175
185
}
176
186
177
187
#[ wasm_bindgen]
@@ -183,17 +193,15 @@ impl DecompressStream {
183
193
let alloc = StandardAlloc :: default ( ) ;
184
194
Self {
185
195
state : BrotliState :: new ( alloc, alloc, alloc) ,
186
- result : BrotliStreamResult :: Init as i32 ,
187
196
total_out : 0 ,
188
- last_input_offset : 0 ,
189
197
}
190
198
}
191
199
192
200
pub fn decompress (
193
201
& mut self ,
194
202
input : Box < [ u8 ] > ,
195
203
output_size : usize ,
196
- ) -> Result < Box < [ u8 ] > , JsValue > {
204
+ ) -> Result < BrotliStreamResult , JsError > {
197
205
let mut output = vec ! [ 0 ; output_size] ;
198
206
let mut available_in = input. len ( ) ;
199
207
let mut input_offset = 0 ;
@@ -211,42 +219,37 @@ impl DecompressStream {
211
219
) {
212
220
BrotliResult :: ResultFailure => {
213
221
// 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 ! (
217
224
"Brotli streaming decompress failed: Error code {}" ,
218
- self . result
225
+ err_code
219
226
) ) )
220
227
}
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
+ } ) ,
226
233
BrotliResult :: ResultSuccess => {
227
234
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
+ } )
231
240
}
232
241
BrotliResult :: NeedsMoreInput => {
233
242
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
+ } )
237
248
}
238
249
}
239
250
}
240
251
241
252
pub fn total_out ( & self ) -> usize {
242
253
self . total_out
243
254
}
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
- }
252
255
}
0 commit comments