@@ -19,8 +19,22 @@ pub enum Data {
1919}
2020
2121#[ napi( object) ]
22- pub struct Options {
22+ pub struct DecOptions {
2323 pub as_buffer : Option < bool > ,
24+ /// do not use `create_external_buffer` to create the output buffer \n
25+ /// set this option to `true` will make the API slower \n
26+ /// for compatibility with electron >= 21 \n
27+ /// see https://www.electronjs.org/blog/v8-memory-cage and https://github.com/electron/electron/issues/35801#issuecomment-1261206333
28+ pub copy_output_data : Option < bool > ,
29+ }
30+
31+ #[ napi( object) ]
32+ pub struct EncOptions {
33+ /// do not use `create_external_buffer` to create the output buffer \n
34+ /// for compatibility with electron >= 21 \n
35+ /// set this option to `true` will make the API slower \n
36+ /// see https://www.electronjs.org/blog/v8-memory-cage and https://github.com/electron/electron/issues/35801#issuecomment-1261206333
37+ pub copy_output_data : Option < bool > ,
2438}
2539
2640impl TryFrom < Either < String , JsBuffer > > for Data {
@@ -34,9 +48,10 @@ impl TryFrom<Either<String, JsBuffer>> for Data {
3448 }
3549}
3650
37- struct Enc {
51+ pub struct Enc {
3852 inner : Encoder ,
3953 data : Data ,
54+ options : Option < EncOptions > ,
4055}
4156
4257#[ napi]
@@ -55,7 +70,17 @@ impl Task for Enc {
5570 }
5671
5772 fn resolve ( & mut self , env : Env , output : Self :: Output ) -> Result < Self :: JsValue > {
58- env. create_buffer_with_data ( output) . map ( |b| b. into_raw ( ) )
73+ if self
74+ . options
75+ . as_ref ( )
76+ . and_then ( |o| o. copy_output_data )
77+ . unwrap_or ( false )
78+ {
79+ env. create_buffer_copy ( output)
80+ } else {
81+ env. create_buffer_with_data ( output)
82+ }
83+ . map ( |b| b. into_raw ( ) )
5984 }
6085
6186 fn finally ( & mut self , env : Env ) -> Result < ( ) > {
@@ -66,16 +91,16 @@ impl Task for Enc {
6691 }
6792}
6893
69- struct Dec {
94+ pub struct Dec {
7095 inner : Decoder ,
7196 data : Data ,
72- as_buffer : bool ,
97+ options : Option < DecOptions > ,
7398}
7499
75100#[ napi]
76101impl Task for Dec {
77102 type Output = Vec < u8 > ;
78- type JsValue = Either < String , Buffer > ;
103+ type JsValue = Either < String , JsBuffer > ;
79104
80105 fn compute ( & mut self ) -> Result < Self :: Output > {
81106 self
@@ -87,9 +112,18 @@ impl Task for Dec {
87112 . map_err ( |e| Error :: new ( Status :: GenericFailure , format ! ( "{}" , e) ) )
88113 }
89114
90- fn resolve ( & mut self , _env : Env , output : Self :: Output ) -> Result < Self :: JsValue > {
91- if self . as_buffer {
92- Ok ( Either :: B ( output. into ( ) ) )
115+ fn resolve ( & mut self , env : Env , output : Self :: Output ) -> Result < Self :: JsValue > {
116+ let opt_ref = self . options . as_ref ( ) ;
117+ if opt_ref. and_then ( |o| o. as_buffer ) . unwrap_or ( true ) {
118+ if opt_ref. and_then ( |o| o. copy_output_data ) . unwrap_or ( false ) {
119+ Ok ( Either :: B (
120+ env. create_buffer_copy ( output) . map ( |o| o. into_raw ( ) ) ?,
121+ ) )
122+ } else {
123+ Ok ( Either :: B (
124+ env. create_buffer_with_data ( output) . map ( |o| o. into_raw ( ) ) ?,
125+ ) )
126+ }
93127 } else {
94128 Ok ( Either :: A ( String :: from_utf8 ( output) . map_err ( |e| {
95129 Error :: new ( Status :: GenericFailure , format ! ( "{}" , e) )
@@ -106,26 +140,32 @@ impl Task for Dec {
106140}
107141
108142#[ napi]
109- pub fn compress_sync ( input : Either < Buffer , String > ) -> Result < Buffer > {
110- let mut enc = Encoder :: new ( ) ;
111- enc
112- . compress_vec ( match input {
113- Either :: A ( ref b) => b. as_ref ( ) ,
114- Either :: B ( ref s) => s. as_bytes ( ) ,
115- } )
116- . map_err ( |e| Error :: new ( napi:: Status :: GenericFailure , format ! ( "{}" , e) ) )
117- . map ( |v| v. into ( ) )
143+ pub fn compress_sync (
144+ env : Env ,
145+ input : Either < String , JsBuffer > ,
146+ options : Option < EncOptions > ,
147+ ) -> Result < JsBuffer > {
148+ let enc = Encoder :: new ( ) ;
149+ let mut encoder = Enc {
150+ inner : enc,
151+ data : Data :: try_from ( input) ?,
152+ options,
153+ } ;
154+ let output = encoder. compute ( ) ?;
155+ encoder. resolve ( env, output)
118156}
119157
120158#[ napi]
121- fn compress (
159+ pub fn compress (
122160 input : Either < String , JsBuffer > ,
161+ options : Option < EncOptions > ,
123162 signal : Option < AbortSignal > ,
124163) -> Result < AsyncTask < Enc > > {
125164 let enc = Encoder :: new ( ) ;
126165 let encoder = Enc {
127166 inner : enc,
128167 data : Data :: try_from ( input) ?,
168+ options,
129169 } ;
130170 match signal {
131171 Some ( s) => Ok ( AsyncTask :: with_signal ( encoder, s) ) ,
@@ -134,44 +174,32 @@ fn compress(
134174}
135175
136176#[ napi]
137- fn uncompress_sync (
138- input : Either < String , Buffer > ,
139- as_buffer : Option < Options > ,
140- ) -> Result < Either < String , Buffer > > {
141- let as_buffer = as_buffer. and_then ( |o| o. as_buffer ) . unwrap_or ( true ) ;
142- let mut dec = Decoder :: new ( ) ;
143- dec
144- . decompress_vec ( match input {
145- Either :: A ( ref s) => s. as_bytes ( ) ,
146- Either :: B ( ref b) => b. as_ref ( ) ,
147- } )
148- . map_err ( |e| Error :: new ( napi:: Status :: GenericFailure , format ! ( "{}" , e) ) )
149- . and_then ( |d| {
150- if as_buffer {
151- Ok ( Either :: B ( d. into ( ) ) )
152- } else {
153- Ok ( Either :: A ( String :: from_utf8 ( d) . map_err ( |e| {
154- Error :: new ( Status :: GenericFailure , format ! ( "{}" , e) )
155- } ) ?) )
156- }
157- } )
177+ pub fn uncompress_sync (
178+ env : Env ,
179+ input : Either < String , JsBuffer > ,
180+ options : Option < DecOptions > ,
181+ ) -> Result < Either < String , JsBuffer > > {
182+ let dec = Decoder :: new ( ) ;
183+ let mut decoder = Dec {
184+ inner : dec,
185+ data : Data :: try_from ( input) ?,
186+ options,
187+ } ;
188+ let output = decoder. compute ( ) ?;
189+ decoder. resolve ( env, output)
158190}
159191
160192#[ napi]
161- fn uncompress (
193+ pub fn uncompress (
162194 input : Either < String , JsBuffer > ,
163- options : Option < Options > ,
195+ options : Option < DecOptions > ,
164196 signal : Option < AbortSignal > ,
165197) -> Result < AsyncTask < Dec > > {
166- let as_buffer = options. and_then ( |o| o. as_buffer ) . unwrap_or ( true ) ;
167198 let dec = Decoder :: new ( ) ;
168199 let decoder = Dec {
169200 inner : dec,
170201 data : Data :: try_from ( input) ?,
171- as_buffer ,
202+ options ,
172203 } ;
173- match signal {
174- Some ( s) => Ok ( AsyncTask :: with_signal ( decoder, s) ) ,
175- None => Ok ( AsyncTask :: new ( decoder) ) ,
176- }
204+ Ok ( AsyncTask :: with_optional_signal ( decoder, signal) )
177205}
0 commit comments