1 /*
2  * Copyright (c) 2024 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  * http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #include "zip_n_exporter.h"
17 
18 #include <cstdio>
19 #include <cstdlib>
20 #include <cstring>
21 #include <memory>
22 #include <sstream>
23 #include <string>
24 #include <tuple>
25 
26 #include "common/common_func.h"
27 #include "common/napi_async_work_callback.h"
28 #include "common/napi_async_work_promise.h"
29 #include "common/napi_class.h"
30 #include "common/napi_func_arg.h"
31 #include "common/napi_business_error.h"
32 #include "securec.h"
33 #include "zip_entity.h"
34 #include "zlib.h"
35 
36 namespace OHOS {
37 namespace AppExecFwk {
38 namespace LIBZIP {
39 using namespace std;
40 static constexpr int32_t ERROR_CODE = -5;
41 static constexpr int32_t MIN_BITS = 0;
42 static constexpr int32_t MAX_BITS = 16;
43 struct AsyncZipArg {
44     const char *zliVersion = nullptr;
45     const char *zErrorMsg = nullptr;
46     uLong zlibCompileFlags = 0;
47     int32_t errCode = 0;
48     uint32_t pending = 0U;
49     int32_t bits = 0;
50     uLong destLen = 0U;
51     int32_t level = 0;
52     uLong sourceLen = 0U;
53     uInt dictLength = 0U;
54     int32_t method = 0;
55     int32_t windowBits = 0;
56     int32_t memLevel = 0;
57     int32_t strategy = 0;
58 
59     AsyncZipArg() = default;
60     ~AsyncZipArg() = default;
61 };
62 
63 struct InOutDesc {
64     napi_env env = nullptr;
65     napi_value func = nullptr;
66     napi_value desc = nullptr;
67 
InOutDescOHOS::AppExecFwk::LIBZIP::InOutDesc68     InOutDesc(napi_env env, napi_value func, napi_value desc) : env(env), func(func), desc(desc) {};
69     ~InOutDesc() = default;
70 };
71 
ZipOutputInfo(napi_env env,std::shared_ptr<AsyncZipArg> arg)72 static NapiValue ZipOutputInfo(napi_env env, std::shared_ptr<AsyncZipArg> arg)
73 {
74     NapiValue obj = NapiValue::CreateObject(env);
75     obj.AddProp({
76         NapiValue::DeclareNapiProperty("status", NapiValue::CreateInt32(env, arg->errCode).val_),
77         NapiValue::DeclareNapiProperty(
78             "destLen", NapiValue::CreateInt64(env, static_cast<int64_t>(arg->destLen)).val_),
79     });
80     return {obj};
81 }
82 
DecompressionOutputInfo(napi_env env,std::shared_ptr<AsyncZipArg> arg)83 static NapiValue DecompressionOutputInfo(napi_env env, std::shared_ptr<AsyncZipArg> arg)
84 {
85     NapiValue obj = NapiValue::CreateObject(env);
86     obj.AddProp({
87         NapiValue::DeclareNapiProperty("status", NapiValue::CreateInt32(env, arg->errCode).val_),
88         NapiValue::DeclareNapiProperty(
89             "destLength", NapiValue::CreateInt64(env, static_cast<int64_t>(arg->destLen)).val_),
90         NapiValue::DeclareNapiProperty(
91             "sourceLength", NapiValue::CreateInt64(env, static_cast<int64_t>(arg->sourceLen)).val_),
92     });
93     return {obj};
94 }
95 
DictionaryOutputInfo(napi_env env,std::shared_ptr<AsyncZipArg> arg)96 static NapiValue DictionaryOutputInfo(napi_env env, std::shared_ptr<AsyncZipArg> arg)
97 {
98     NapiValue obj = NapiValue::CreateObject(env);
99     obj.AddProp({
100         NapiValue::DeclareNapiProperty("status", NapiValue::CreateInt32(env, arg->errCode).val_),
101         NapiValue::DeclareNapiProperty("dictionaryLength", NapiValue::CreateInt32(env, arg->dictLength).val_),
102     });
103     return {obj};
104 }
105 
DeflatePendingOutputInfo(napi_env env,std::shared_ptr<AsyncZipArg> arg)106 static NapiValue DeflatePendingOutputInfo(napi_env env, std::shared_ptr<AsyncZipArg> arg)
107 {
108     NapiValue obj = NapiValue::CreateObject(env);
109     obj.AddProp({
110         NapiValue::DeclareNapiProperty("status", NapiValue::CreateInt32(env, arg->errCode).val_),
111         NapiValue::DeclareNapiProperty("pending", NapiValue::CreateInt32(env, arg->pending).val_),
112         NapiValue::DeclareNapiProperty("bits", NapiValue::CreateInt32(env, arg->bits).val_),
113     });
114     return {obj};
115 }
116 
GetZStreamInfo(napi_env env,ZipEntity * zipEntity)117 static NapiValue GetZStreamInfo(napi_env env, ZipEntity *zipEntity)
118 {
119     NapiValue obj = NapiValue::CreateObject(env);
120     obj.AddProp({
121         NapiValue::DeclareNapiProperty("availableIn", NapiValue::CreateInt32(env, zipEntity->zs.get()->avail_in).val_),
122         NapiValue::DeclareNapiProperty("totalIn", NapiValue::CreateInt64(env, zipEntity->zs.get()->total_in).val_),
123         NapiValue::DeclareNapiProperty(
124             "availableOut", NapiValue::CreateInt32(env, zipEntity->zs.get()->avail_out).val_),
125         NapiValue::DeclareNapiProperty("totalOut", NapiValue::CreateInt64(env, zipEntity->zs.get()->total_out).val_),
126         NapiValue::DeclareNapiProperty("dataType", NapiValue::CreateInt32(env, zipEntity->zs.get()->data_type).val_),
127         NapiValue::DeclareNapiProperty("adler", NapiValue::CreateInt64(env, zipEntity->zs.get()->adler).val_),
128     });
129     return { obj };
130 }
131 
Constructor(napi_env env,napi_callback_info info)132 napi_value ZipNExporter::Constructor(napi_env env, napi_callback_info info)
133 {
134     NapiFuncArg funcArg(env, info);
135     if (!funcArg.InitArgs(ArgumentCount::ZERO)) {
136         NapiBusinessError().ThrowErr(env, EINVAL);
137         return nullptr;
138     }
139 
140     unique_ptr<ZipEntity> zipEntity = make_unique<ZipEntity>();
141     if (!NapiClass::SetEntityFor<ZipEntity>(env, funcArg.GetThisVar(), move(zipEntity))) {
142         NapiBusinessError().ThrowErr(env, EFAULT);
143         return nullptr;
144     }
145     return funcArg.GetThisVar();
146 }
147 
DeflateExport()148 vector<napi_property_descriptor> ZipNExporter::DeflateExport()
149 {
150     vector<napi_property_descriptor> props = {
151         NapiValue::DeclareNapiFunction("deflateInit", DeflateInit),
152         NapiValue::DeclareNapiFunction("deflateInit2", DeflateInit2),
153         NapiValue::DeclareNapiFunction("deflate", Deflate),
154         NapiValue::DeclareNapiFunction("deflateEnd", DeflateEnd),
155         NapiValue::DeclareNapiFunction("deflateBound", DeflateBound),
156         NapiValue::DeclareNapiFunction("deflateReset", DeflateReset),
157         NapiValue::DeclareNapiFunction("deflateResetKeep", DeflateResetKeep),
158         NapiValue::DeclareNapiFunction("deflateParams", DeflateParams),
159         NapiValue::DeclareNapiFunction("deflatePrime", DeflatePrime),
160         NapiValue::DeclareNapiFunction("deflateTune", DeflateTune),
161         NapiValue::DeclareNapiFunction("deflateSetDictionary", DeflateSetDictionary),
162         NapiValue::DeclareNapiFunction("deflateGetDictionary", DeflateGetDictionary),
163         NapiValue::DeclareNapiFunction("deflateSetHeader", DeflateSetHeader),
164         NapiValue::DeclareNapiFunction("deflatePending", DeflatePending),
165         NapiValue::DeclareNapiFunction("deflateCopy", DeflateCopy),
166     };
167     return props;
168 }
169 
InflateExport()170 vector<napi_property_descriptor> ZipNExporter::InflateExport()
171 {
172     vector<napi_property_descriptor> props = {
173         NapiValue::DeclareNapiFunction("inflateInit", InflateInit),
174         NapiValue::DeclareNapiFunction("inflateInit2", InflateInit2),
175         NapiValue::DeclareNapiFunction("inflateSync", InflateSync),
176         NapiValue::DeclareNapiFunction("inflate", Inflate),
177         NapiValue::DeclareNapiFunction("inflateEnd", InflateEnd),
178         NapiValue::DeclareNapiFunction("inflateSetDictionary", InflateSetDictionary),
179         NapiValue::DeclareNapiFunction("inflateGetDictionary", InflateGetDictionary),
180         NapiValue::DeclareNapiFunction("inflateGetHeader", InflateGetHeader),
181         NapiValue::DeclareNapiFunction("inflateReset", InflateReset),
182         NapiValue::DeclareNapiFunction("inflateReset2", InflateReset2),
183         NapiValue::DeclareNapiFunction("inflateResetKeep", InflateResetKeep),
184         NapiValue::DeclareNapiFunction("inflateBackInit", InflateBackInit),
185         NapiValue::DeclareNapiFunction("inflateBack", InflateBack),
186         NapiValue::DeclareNapiFunction("inflateBackEnd", InflateBackEnd),
187         NapiValue::DeclareNapiFunction("inflateCodesUsed", InflateCodesUsed),
188         NapiValue::DeclareNapiFunction("inflatePrime", InflatePrime),
189         NapiValue::DeclareNapiFunction("inflateMark", InflateMark),
190         NapiValue::DeclareNapiFunction("inflateValidate", InflateValidate),
191         NapiValue::DeclareNapiFunction("inflateSyncPoint", InflateSyncPoint),
192         NapiValue::DeclareNapiFunction("inflateCopy", InflateCopy),
193     };
194     return props;
195 }
196 
Export()197 bool ZipNExporter::Export()
198 {
199     vector<napi_property_descriptor> props = {
200         NapiValue::DeclareNapiFunction("setZStream", SetZStream),
201         NapiValue::DeclareNapiFunction("getZStream", GetZStream),
202         NapiValue::DeclareNapiFunction("getZStreamSync", GetZStreamSync),
203         NapiValue::DeclareNapiFunction("zlibVersion", ZlibVersion),
204         NapiValue::DeclareNapiFunction("zError", ZError),
205         NapiValue::DeclareNapiFunction("zlibCompileFlags", ZlibCompileFlags),
206         NapiValue::DeclareNapiFunction("compress", Compress),
207         NapiValue::DeclareNapiFunction("compress2", Compress2),
208         NapiValue::DeclareNapiFunction("compressBound", CompressBound),
209         NapiValue::DeclareNapiFunction("uncompress", UnCompress),
210         NapiValue::DeclareNapiFunction("uncompress2", UnCompress2),
211     };
212     for (const auto &prop : DeflateExport()) {
213         props.push_back(prop);
214     }
215 
216     for (const auto &prop : InflateExport()) {
217         props.push_back(prop);
218     }
219 
220     string className = GetClassName();
221     bool succ = false;
222     napi_value cls = nullptr;
223     tie(succ, cls) = NapiClass::DefineClass(exports_.env_, className, ZipNExporter::Constructor, move(props));
224     if (!succ) {
225         NapiBusinessError().ThrowErr(exports_.env_, "Failed to define class");
226         return false;
227     }
228     succ = NapiClass::SaveClass(exports_.env_, className, cls);
229     if (!succ) {
230         NapiBusinessError().ThrowErr(exports_.env_, "Failed to save class");
231         return false;
232     }
233 
234     return exports_.AddProp(className, cls);
235 }
236 
GetClassName()237 string ZipNExporter::GetClassName()
238 {
239     return ZipNExporter::className_;
240 }
241 
ZipNExporter(napi_env env,napi_value exports)242 ZipNExporter::ZipNExporter(napi_env env, napi_value exports) : NapiExporter(env, exports)
243 {}
244 
~ZipNExporter()245 ZipNExporter::~ZipNExporter()
246 {}
247 
SetZStream(napi_env env,napi_callback_info info)248 napi_value ZipNExporter::SetZStream(napi_env env, napi_callback_info info)
249 {
250     NapiFuncArg funcArg(env, info);
251     if (!funcArg.InitArgs(ArgumentCount::ONE, ArgumentCount::TWO)) {
252         NapiBusinessError().ThrowErr(env, EINVAL);
253         return nullptr;
254     }
255 
256     bool succ = CommonFunc::SetZStreamValue(env, funcArg);
257     if (!succ) {
258         return nullptr;
259     }
260 
261     auto cbExec = [](napi_env env) -> NapiBusinessError { return NapiBusinessError(ERRNO_NOERR); };
262 
263     auto cbCompl = [](napi_env env, NapiBusinessError err) -> NapiValue {
264         if (err) {
265             return {env, err.GetNapiErr(env)};
266         }
267         return {NapiValue::CreateUndefined(env)};
268     };
269 
270     NapiValue thisVar(env, funcArg.GetThisVar());
271     if (funcArg.GetArgc() == ArgumentCount::ONE) {
272         return NapiAsyncWorkPromise(env, thisVar).Schedule(PROCEDURE_ZIP_NAME, cbExec, cbCompl).val_;
273     }
274 
275     return NapiValue::CreateUndefined(env).val_;
276 }
277 
GetZStreamSync(napi_env env,napi_callback_info info)278 napi_value ZipNExporter::GetZStreamSync(napi_env env, napi_callback_info info)
279 {
280     NapiFuncArg funcArg(env, info);
281     if (!funcArg.InitArgs(ArgumentCount::ZERO, ArgumentCount::ONE)) {
282         NapiBusinessError().ThrowErr(env, EINVAL);
283         return nullptr;
284     }
285 
286     /* To get entity */
287     auto zipEntity = NapiClass::GetEntityOf<ZipEntity>(env, funcArg.GetThisVar());
288     if (!zipEntity || !zipEntity->zs) {
289         NapiBusinessError().ThrowErr(env, EFAULT);
290         return nullptr;
291     }
292 
293     NapiValue obj = NapiValue::CreateObject(env);
294     obj.AddProp({
295         NapiValue::DeclareNapiProperty(
296             "availableIn", NapiValue::CreateInt32(env, zipEntity->zs.get()->avail_in).val_),
297         NapiValue::DeclareNapiProperty("totalIn", NapiValue::CreateInt64(env, zipEntity->zs.get()->total_in).val_),
298         NapiValue::DeclareNapiProperty(
299             "availableOut", NapiValue::CreateInt32(env, zipEntity->zs.get()->avail_out).val_),
300         NapiValue::DeclareNapiProperty("totalOut", NapiValue::CreateInt64(env, zipEntity->zs.get()->total_out).val_),
301         NapiValue::DeclareNapiProperty("dataType", NapiValue::CreateInt32(env, zipEntity->zs.get()->data_type).val_),
302         NapiValue::DeclareNapiProperty("adler", NapiValue::CreateInt64(env, zipEntity->zs.get()->adler).val_),
303     });
304 
305     return obj.val_;
306 }
307 
GetZStream(napi_env env,napi_callback_info info)308 napi_value ZipNExporter::GetZStream(napi_env env, napi_callback_info info)
309 {
310     NapiFuncArg funcArg(env, info);
311     if (!funcArg.InitArgs(ArgumentCount::ZERO, ArgumentCount::ONE)) {
312         NapiBusinessError().ThrowErr(env, EINVAL);
313         return nullptr;
314     }
315 
316     /* To get entity */
317     auto zipEntity = NapiClass::GetEntityOf<ZipEntity>(env, funcArg.GetThisVar());
318     if (!zipEntity) {
319         NapiBusinessError().ThrowErr(env, EFAULT);
320         return nullptr;
321     }
322 
323     auto cbExec = [](napi_env env) -> NapiBusinessError { return NapiBusinessError(ERRNO_NOERR); };
324 
325     auto cbCompl = [zipEntity](napi_env env, NapiBusinessError err) -> NapiValue {
326         if (err) {
327             return {env, err.GetNapiErr(env)};
328         } else if (!zipEntity || !zipEntity->zs) {
329             return {NapiValue::CreateUndefined(env)};
330         }
331 
332         NapiValue obj = GetZStreamInfo(env, zipEntity);
333         return {obj};
334     };
335 
336     NapiValue thisVar(env, funcArg.GetThisVar());
337     if (funcArg.GetArgc() == ArgumentCount::ZERO) {
338         return NapiAsyncWorkPromise(env, thisVar).Schedule(PROCEDURE_ZIP_NAME, cbExec, cbCompl).val_;
339     }
340 
341     return NapiValue::CreateUndefined(env).val_;
342 }
343 
ZlibVersion(napi_env env,napi_callback_info info)344 napi_value ZipNExporter::ZlibVersion(napi_env env, napi_callback_info info)
345 {
346     NapiFuncArg funcArg(env, info);
347     if (!funcArg.InitArgs(ArgumentCount::ZERO, ArgumentCount::ONE)) {
348         NapiBusinessError().ThrowErr(env, EINVAL);
349         return nullptr;
350     }
351 
352     /* To get entity */
353     auto zipEntity = NapiClass::GetEntityOf<ZipEntity>(env, funcArg.GetThisVar());
354     if (!zipEntity) {
355         NapiBusinessError().ThrowErr(env, EFAULT);
356         return nullptr;
357     }
358 
359     auto arg = make_shared<AsyncZipArg>();
360     auto cbExec = [arg](napi_env env) -> NapiBusinessError {
361         if (!arg) {
362             return NapiBusinessError(EFAULT, true);
363         }
364         arg->zliVersion = zlibVersion();
365         return NapiBusinessError(ERRNO_NOERR);
366     };
367 
368     auto cbCompl = [arg](napi_env env, NapiBusinessError err) -> NapiValue {
369         if (err) {
370             return {env, err.GetNapiErr(env)};
371         }
372         if (!arg) {
373             return {NapiValue::CreateUndefined(env)};
374         }
375         return {NapiValue::CreateUTF8String(env, string(reinterpret_cast<const char *>(arg->zliVersion)))};
376     };
377 
378     NapiValue thisVar(env, funcArg.GetThisVar());
379     if (funcArg.GetArgc() == ArgumentCount::ZERO) {
380         return NapiAsyncWorkPromise(env, thisVar).Schedule(PROCEDURE_ZIP_NAME, cbExec, cbCompl).val_;
381     }
382 
383     return NapiValue::CreateUndefined(env).val_;
384 }
385 
ZError(napi_env env,napi_callback_info info)386 napi_value ZipNExporter::ZError(napi_env env, napi_callback_info info)
387 {
388     NapiFuncArg funcArg(env, info);
389     if (!funcArg.InitArgs(ArgumentCount::ONE, ArgumentCount::TWO)) {
390         NapiBusinessError().ThrowErr(env, EINVAL);
391         return nullptr;
392     }
393 
394     /* To get entity */
395     auto zipEntity = NapiClass::GetEntityOf<ZipEntity>(env, funcArg.GetThisVar());
396     if (!zipEntity) {
397         NapiBusinessError().ThrowErr(env, EFAULT);
398         return nullptr;
399     }
400 
401     bool succ = false;
402     int32_t zlibError = 0;
403     tie(succ, zlibError) = CommonFunc::GetZErrorArg(env, funcArg);
404     if (!succ) {
405         return nullptr;
406     }
407 
408     auto arg = make_shared<AsyncZipArg>();
409     auto cbExec = [arg, zlibError](napi_env env) -> NapiBusinessError {
410         if (!arg) {
411             return NapiBusinessError(EFAULT, true);
412         }
413         arg->zErrorMsg = zError(zlibError);
414         return NapiBusinessError(ERRNO_NOERR);
415     };
416 
417     auto cbCompl = [arg](napi_env env, NapiBusinessError err) -> NapiValue {
418         if (err) {
419             return {env, err.GetNapiErr(env)};
420         }
421         if (!arg) {
422             return {NapiValue::CreateUndefined(env)};
423         }
424         return {NapiValue::CreateUTF8String(env, string(reinterpret_cast<const char *>(arg->zErrorMsg)))};
425     };
426 
427     NapiValue thisVar(env, funcArg.GetThisVar());
428     if (funcArg.GetArgc() == ArgumentCount::ONE) {
429         return NapiAsyncWorkPromise(env, thisVar).Schedule(PROCEDURE_ZIP_NAME, cbExec, cbCompl).val_;
430     }
431 
432     return NapiValue::CreateUndefined(env).val_;
433 }
434 
ZlibCompileFlags(napi_env env,napi_callback_info info)435 napi_value ZipNExporter::ZlibCompileFlags(napi_env env, napi_callback_info info)
436 {
437     NapiFuncArg funcArg(env, info);
438     if (!funcArg.InitArgs(ArgumentCount::ZERO, ArgumentCount::ONE)) {
439         NapiBusinessError().ThrowErr(env, EINVAL);
440         return nullptr;
441     }
442 
443     /* To get entity */
444     auto zipEntity = NapiClass::GetEntityOf<ZipEntity>(env, funcArg.GetThisVar());
445     if (!zipEntity) {
446         NapiBusinessError().ThrowErr(env, EFAULT);
447         return nullptr;
448     }
449 
450     auto arg = make_shared<AsyncZipArg>();
451     auto cbExec = [arg](napi_env env) -> NapiBusinessError {
452         if (!arg) {
453             return NapiBusinessError(EFAULT, true);
454         }
455         arg->zlibCompileFlags = zlibCompileFlags();
456         return NapiBusinessError(ERRNO_NOERR);
457     };
458 
459     auto cbCompl = [arg](napi_env env, NapiBusinessError err) -> NapiValue {
460         if (err) {
461             return {env, err.GetNapiErr(env)};
462         }
463         if (!arg) {
464             return {NapiValue::CreateUndefined(env)};
465         }
466         return {NapiValue::NapiValue::CreateInt32(env, arg->zlibCompileFlags)};
467     };
468 
469     NapiValue thisVar(env, funcArg.GetThisVar());
470     if (funcArg.GetArgc() == ArgumentCount::ZERO) {
471         return NapiAsyncWorkPromise(env, thisVar).Schedule(PROCEDURE_ZIP_NAME, cbExec, cbCompl).val_;
472     }
473 
474     return NapiValue::CreateUndefined(env).val_;
475 }
476 
DeflateInit(napi_env env,napi_callback_info info)477 napi_value ZipNExporter::DeflateInit(napi_env env, napi_callback_info info)
478 {
479     NapiFuncArg funcArg(env, info);
480     if (!funcArg.InitArgs(ArgumentCount::TWO, ArgumentCount::THREE)) {
481         NapiBusinessError().ThrowErr(env, EINVAL);
482         return nullptr;
483     }
484 
485     /* To get entity */
486     auto zipEntity = NapiClass::GetEntityOf<ZipEntity>(env, funcArg.GetThisVar());
487     if (!zipEntity) {
488         NapiBusinessError().ThrowErr(env, EFAULT);
489         return nullptr;
490     }
491 
492     bool succ = false;
493     z_stream zStream = {};
494     int32_t level = 0;
495     tie(succ, zStream, level) = CommonFunc::GetDeflateInitArg(env, funcArg);
496     if (!succ) {
497         return nullptr;
498     }
499 
500     auto arg = make_shared<AsyncZipArg>();
501     auto cbExec = [arg, zipEntity, zStream, level](napi_env env) -> NapiBusinessError {
502         if (!arg || !zipEntity) {
503             return NapiBusinessError(EFAULT, true);
504         }
505         std::unique_ptr<z_stream> zs = std::make_unique<z_stream>(zStream);
506         arg->errCode = deflateInit(zs.get(), level);
507         if (arg->errCode < 0) {
508             return NapiBusinessError(arg->errCode, true);
509         }
510         zipEntity->zs.swap(zs);
511         return NapiBusinessError(ERRNO_NOERR);
512     };
513 
514     auto cbCompl = [arg](napi_env env, NapiBusinessError err) -> NapiValue {
515         if (err) {
516             return {env, err.GetNapiErr(env)};
517         }
518         if (!arg) {
519             return {NapiValue::CreateUndefined(env)};
520         }
521         return {NapiValue::CreateInt32(env, arg->errCode)};
522     };
523 
524     NapiValue thisVar(env, funcArg.GetThisVar());
525     if (funcArg.GetArgc() == ArgumentCount::TWO) {
526         return NapiAsyncWorkPromise(env, thisVar).Schedule(PROCEDURE_ZIP_NAME, cbExec, cbCompl).val_;
527     }
528 
529     return NapiValue::CreateUndefined(env).val_;
530 }
531 
DeflateInit2(napi_env env,napi_callback_info info)532 napi_value ZipNExporter::DeflateInit2(napi_env env, napi_callback_info info)
533 {
534     NapiFuncArg funcArg(env, info);
535     if (!funcArg.InitArgs(ArgumentCount::SIX, ArgumentCount::SEVEN)) {
536         NapiBusinessError().ThrowErr(env, EINVAL);
537         return nullptr;
538     }
539 
540     /* To get entity */
541     auto zipEntity = NapiClass::GetEntityOf<ZipEntity>(env, funcArg.GetThisVar());
542     if (!zipEntity) {
543         NapiBusinessError().ThrowErr(env, EFAULT);
544         return nullptr;
545     }
546 
547     auto arg = make_shared<AsyncZipArg>();
548     bool succ = false;
549     z_stream zStream = {};
550     tie(succ, zStream, arg->level, arg->method, arg->windowBits, arg->memLevel, arg->strategy) =
551         CommonFunc::GetDeflateInit2Arg(env, funcArg);
552     if (!succ) {
553         return nullptr;
554     }
555 
556     auto cbExec = [arg, zipEntity, zStream](napi_env env) -> NapiBusinessError {
557         if (!arg || !zipEntity) {
558             return NapiBusinessError(EFAULT, true);
559         }
560         std::unique_ptr<z_stream> zs = std::make_unique<z_stream>(zStream);
561         arg->errCode = deflateInit2(zs.get(), arg->level, arg->method, arg->windowBits, arg->memLevel, arg->strategy);
562         if (arg->errCode < 0) {
563             return NapiBusinessError(arg->errCode, true);
564         }
565         zipEntity->zs.swap(zs);
566         return NapiBusinessError(ERRNO_NOERR);
567     };
568 
569     auto cbCompl = [arg](napi_env env, NapiBusinessError err) -> NapiValue {
570         if (err) {
571             return {env, err.GetNapiErr(env)};
572         }
573         if (!arg) {
574             return {NapiValue::CreateUndefined(env)};
575         }
576         return {NapiValue::CreateInt32(env, arg->errCode)};
577     };
578 
579     NapiValue thisVar(env, funcArg.GetThisVar());
580     if (funcArg.GetArgc() == ArgumentCount::SIX) {
581         return NapiAsyncWorkPromise(env, thisVar).Schedule(PROCEDURE_ZIP_NAME, cbExec, cbCompl).val_;
582     }
583 
584     return NapiValue::CreateUndefined(env).val_;
585 }
586 
Deflate(napi_env env,napi_callback_info info)587 napi_value ZipNExporter::Deflate(napi_env env, napi_callback_info info)
588 {
589     NapiFuncArg funcArg(env, info);
590     if (!funcArg.InitArgs(ArgumentCount::TWO, ArgumentCount::THREE)) {
591         NapiBusinessError().ThrowErr(env, EINVAL);
592         return nullptr;
593     }
594 
595     /* To get entity */
596     auto zipEntity = NapiClass::GetEntityOf<ZipEntity>(env, funcArg.GetThisVar());
597     if (!zipEntity) {
598         NapiBusinessError().ThrowErr(env, EFAULT);
599         return nullptr;
600     }
601 
602     bool succ = false;
603     int32_t flush = 0;
604     tie(succ, flush) = CommonFunc::GetDeflateArg(env, funcArg);
605     if (!succ) {
606         return nullptr;
607     }
608 
609     auto arg = make_shared<AsyncZipArg>();
610     auto cbExec = [arg, zipEntity, flush](napi_env env) -> NapiBusinessError {
611         if (!arg || !zipEntity || !zipEntity->zs) {
612             return NapiBusinessError(EFAULT, true);
613         }
614         arg->errCode = deflate(zipEntity->zs.get(), flush);
615         if (arg->errCode < 0) {
616             return NapiBusinessError(arg->errCode, true);
617         }
618         return NapiBusinessError(ERRNO_NOERR);
619     };
620 
621     auto cbCompl = [arg](napi_env env, NapiBusinessError err) -> NapiValue {
622         if (err) {
623             return {env, err.GetNapiErr(env)};
624         }
625         if (!arg) {
626             return {NapiValue::CreateUndefined(env)};
627         }
628         return {NapiValue::CreateInt32(env, arg->errCode)};
629     };
630 
631     NapiValue thisVar(env, funcArg.GetThisVar());
632     if (funcArg.GetArgc() == ArgumentCount::TWO) {
633         return NapiAsyncWorkPromise(env, thisVar).Schedule(PROCEDURE_ZIP_NAME, cbExec, cbCompl).val_;
634     }
635 
636     return NapiValue::CreateUndefined(env).val_;
637 }
638 
DeflateEnd(napi_env env,napi_callback_info info)639 napi_value ZipNExporter::DeflateEnd(napi_env env, napi_callback_info info)
640 {
641     NapiFuncArg funcArg(env, info);
642     if (!funcArg.InitArgs(ArgumentCount::ONE, ArgumentCount::TWO)) {
643         NapiBusinessError().ThrowErr(env, EINVAL);
644         return nullptr;
645     }
646 
647     /* To get entity */
648     auto zipEntity = NapiClass::GetEntityOf<ZipEntity>(env, funcArg.GetThisVar());
649     if (!zipEntity) {
650         NapiBusinessError().ThrowErr(env, EFAULT);
651         return nullptr;
652     }
653 
654     bool succ = CommonFunc::SetZStreamValue(env, funcArg);
655     if (!succ) {
656         return nullptr;
657     }
658 
659     auto arg = make_shared<AsyncZipArg>();
660     auto cbExec = [arg, zipEntity](napi_env env) -> NapiBusinessError {
661         if (!arg || !zipEntity || !zipEntity->zs) {
662             return NapiBusinessError(EFAULT, true);
663         }
664         arg->errCode = deflateEnd(zipEntity->zs.get());
665         if (arg->errCode < 0) {
666             return NapiBusinessError(arg->errCode, true);
667         }
668         return NapiBusinessError(ERRNO_NOERR);
669     };
670 
671     auto cbCompl = [arg](napi_env env, NapiBusinessError err) -> NapiValue {
672         if (err) {
673             return {env, err.GetNapiErr(env)};
674         }
675         if (!arg) {
676             return {NapiValue::CreateUndefined(env)};
677         }
678         return {NapiValue::CreateInt32(env, arg->errCode)};
679     };
680 
681     NapiValue thisVar(env, funcArg.GetThisVar());
682     if (funcArg.GetArgc() == ArgumentCount::ONE) {
683         return NapiAsyncWorkPromise(env, thisVar).Schedule(PROCEDURE_ZIP_NAME, cbExec, cbCompl).val_;
684     }
685 
686     return NapiValue::CreateUndefined(env).val_;
687 }
688 
DeflateBound(napi_env env,napi_callback_info info)689 napi_value ZipNExporter::DeflateBound(napi_env env, napi_callback_info info)
690 {
691     NapiFuncArg funcArg(env, info);
692     if (!funcArg.InitArgs(ArgumentCount::TWO, ArgumentCount::THREE)) {
693         NapiBusinessError().ThrowErr(env, EINVAL);
694         return nullptr;
695     }
696 
697     /* To get entity */
698     auto zipEntity = NapiClass::GetEntityOf<ZipEntity>(env, funcArg.GetThisVar());
699     if (!zipEntity) {
700         NapiBusinessError().ThrowErr(env, EFAULT);
701         return nullptr;
702     }
703 
704     bool succ = CommonFunc::SetZStreamValue(env, funcArg);
705     if (!succ) {
706         return nullptr;
707     }
708 
709     uint32_t sourceLen = 0;
710     tie(succ, sourceLen) = CommonFunc::UnwrapInt64Params(env, funcArg);
711     if (!succ) {
712         return nullptr;
713     }
714 
715     auto arg = make_shared<AsyncZipArg>();
716     auto cbExec = [arg, zipEntity, sourceLen](napi_env env) -> NapiBusinessError {
717         if (!arg || !zipEntity || !zipEntity->zs) {
718             return NapiBusinessError(EFAULT, true);
719         }
720         arg->errCode = static_cast<int32_t>(deflateBound(zipEntity->zs.get(), sourceLen));
721         return NapiBusinessError(ERRNO_NOERR);
722     };
723 
724     auto cbCompl = [arg](napi_env env, NapiBusinessError err) -> NapiValue {
725         if (err) {
726             return {env, err.GetNapiErr(env)};
727         }
728         if (!arg) {
729             return {NapiValue::CreateUndefined(env)};
730         }
731         return {NapiValue::CreateInt32(env, arg->errCode)};
732     };
733 
734     NapiValue thisVar(env, funcArg.GetThisVar());
735     if (funcArg.GetArgc() == ArgumentCount::TWO) {
736         return NapiAsyncWorkPromise(env, thisVar).Schedule(PROCEDURE_ZIP_NAME, cbExec, cbCompl).val_;
737     }
738 
739     return NapiValue::CreateUndefined(env).val_;
740 }
741 
DeflateReset(napi_env env,napi_callback_info info)742 napi_value ZipNExporter::DeflateReset(napi_env env, napi_callback_info info)
743 {
744     NapiFuncArg funcArg(env, info);
745     if (!funcArg.InitArgs(ArgumentCount::ONE, ArgumentCount::TWO)) {
746         NapiBusinessError().ThrowErr(env, EINVAL);
747         return nullptr;
748     }
749 
750     /* To get entity */
751     auto zipEntity = NapiClass::GetEntityOf<ZipEntity>(env, funcArg.GetThisVar());
752     if (!zipEntity) {
753         NapiBusinessError().ThrowErr(env, EFAULT);
754         return nullptr;
755     }
756 
757     bool succ = CommonFunc::SetZStreamValue(env, funcArg);
758     if (!succ) {
759         return nullptr;
760     }
761 
762     auto arg = make_shared<AsyncZipArg>();
763     auto cbExec = [arg, zipEntity](napi_env env) -> NapiBusinessError {
764         if (!arg || !zipEntity || !zipEntity->zs) {
765             return NapiBusinessError(EFAULT, true);
766         }
767         arg->errCode = deflateReset(zipEntity->zs.get());
768         if (arg->errCode < 0) {
769             return NapiBusinessError(arg->errCode, true);
770         }
771         return NapiBusinessError(ERRNO_NOERR);
772     };
773 
774     auto cbCompl = [arg](napi_env env, NapiBusinessError err) -> NapiValue {
775         if (err) {
776             return {env, err.GetNapiErr(env)};
777         }
778         if (!arg) {
779             return {NapiValue::CreateUndefined(env)};
780         }
781         return {NapiValue::CreateInt32(env, arg->errCode)};
782     };
783 
784     NapiValue thisVar(env, funcArg.GetThisVar());
785     if (funcArg.GetArgc() == ArgumentCount::ONE) {
786         return NapiAsyncWorkPromise(env, thisVar).Schedule(PROCEDURE_ZIP_NAME, cbExec, cbCompl).val_;
787     }
788 
789     return NapiValue::CreateUndefined(env).val_;
790 }
791 
DeflateResetKeep(napi_env env,napi_callback_info info)792 napi_value ZipNExporter::DeflateResetKeep(napi_env env, napi_callback_info info)
793 {
794     NapiFuncArg funcArg(env, info);
795     if (!funcArg.InitArgs(ArgumentCount::ONE, ArgumentCount::TWO)) {
796         NapiBusinessError().ThrowErr(env, EINVAL);
797         return nullptr;
798     }
799 
800     /* To get entity */
801     auto zipEntity = NapiClass::GetEntityOf<ZipEntity>(env, funcArg.GetThisVar());
802     if (!zipEntity) {
803         NapiBusinessError().ThrowErr(env, EFAULT);
804         return nullptr;
805     }
806 
807     bool succ = CommonFunc::SetZStreamValue(env, funcArg);
808     if (!succ) {
809         return nullptr;
810     }
811 
812     auto arg = make_shared<AsyncZipArg>();
813     auto cbExec = [arg, zipEntity](napi_env env) -> NapiBusinessError {
814         if (!arg || !zipEntity || !zipEntity->zs) {
815             return NapiBusinessError(EFAULT, true);
816         }
817         arg->errCode = deflateResetKeep(zipEntity->zs.get());
818         if (arg->errCode < 0) {
819             return NapiBusinessError(arg->errCode, true);
820         }
821         return NapiBusinessError(ERRNO_NOERR);
822     };
823 
824     auto cbCompl = [arg](napi_env env, NapiBusinessError err) -> NapiValue {
825         if (err) {
826             return {env, err.GetNapiErr(env)};
827         }
828         if (!arg) {
829             return {NapiValue::CreateUndefined(env)};
830         }
831         return {NapiValue::CreateInt32(env, arg->errCode)};
832     };
833 
834     NapiValue thisVar(env, funcArg.GetThisVar());
835     if (funcArg.GetArgc() == ArgumentCount::ONE) {
836         return NapiAsyncWorkPromise(env, thisVar).Schedule(PROCEDURE_ZIP_NAME, cbExec, cbCompl).val_;
837     }
838 
839     return NapiValue::CreateUndefined(env).val_;
840 }
841 
DeflateParams(napi_env env,napi_callback_info info)842 napi_value ZipNExporter::DeflateParams(napi_env env, napi_callback_info info)
843 {
844     NapiFuncArg funcArg(env, info);
845     if (!funcArg.InitArgs(ArgumentCount::THREE, ArgumentCount::FOUR)) {
846         NapiBusinessError().ThrowErr(env, EINVAL);
847         return nullptr;
848     }
849 
850     /* To get entity */
851     auto zipEntity = NapiClass::GetEntityOf<ZipEntity>(env, funcArg.GetThisVar());
852     if (!zipEntity) {
853         NapiBusinessError().ThrowErr(env, EFAULT);
854         return nullptr;
855     }
856 
857     bool succ = false;
858     int32_t level = 0;
859     int32_t strategy = 0;
860     tie(succ, level, strategy) = CommonFunc::UnwrapTwoIntParams(env, funcArg);
861     if (!succ) {
862         return nullptr;
863     }
864 
865     auto arg = make_shared<AsyncZipArg>();
866     auto cbExec = [arg, zipEntity, level, strategy](napi_env env) -> NapiBusinessError {
867         if (!arg || !zipEntity || !zipEntity->zs) {
868             return NapiBusinessError(EFAULT, true);
869         }
870         arg->errCode = deflateParams(zipEntity->zs.get(), level, strategy);
871         if (arg->errCode < 0) {
872             return NapiBusinessError(arg->errCode, true);
873         }
874         return NapiBusinessError(ERRNO_NOERR);
875     };
876 
877     auto cbCompl = [arg](napi_env env, NapiBusinessError err) -> NapiValue {
878         if (err) {
879             return {env, err.GetNapiErr(env)};
880         }
881         if (!arg) {
882             return {NapiValue::CreateUndefined(env)};
883         }
884         return {NapiValue::CreateInt32(env, arg->errCode)};
885     };
886 
887     NapiValue thisVar(env, funcArg.GetThisVar());
888     if (funcArg.GetArgc() == ArgumentCount::THREE) {
889         return NapiAsyncWorkPromise(env, thisVar).Schedule(PROCEDURE_ZIP_NAME, cbExec, cbCompl).val_;
890     }
891 
892     return NapiValue::CreateUndefined(env).val_;
893 }
894 
DeflatePrime(napi_env env,napi_callback_info info)895 napi_value ZipNExporter::DeflatePrime(napi_env env, napi_callback_info info)
896 {
897     NapiFuncArg funcArg(env, info);
898     if (!funcArg.InitArgs(ArgumentCount::THREE, ArgumentCount::FOUR)) {
899         NapiBusinessError().ThrowErr(env, EINVAL);
900         return nullptr;
901     }
902 
903     /* To get entity */
904     auto zipEntity = NapiClass::GetEntityOf<ZipEntity>(env, funcArg.GetThisVar());
905     if (!zipEntity) {
906         NapiBusinessError().ThrowErr(env, EFAULT);
907         return nullptr;
908     }
909 
910     bool succ = false;
911     int32_t bits = 0;
912     int32_t value = 0;
913     tie(succ, bits, value) = CommonFunc::UnwrapTwoIntParams(env, funcArg);
914     if (!succ) {
915         return nullptr;
916     } else if (bits < MIN_BITS || bits > MAX_BITS) {
917         NapiBusinessError().ThrowErr(env, EINVAL);
918         return nullptr;
919     }
920 
921     auto arg = make_shared<AsyncZipArg>();
922     auto cbExec = [arg, zipEntity, bits, value](napi_env env) -> NapiBusinessError {
923         if (!arg || !zipEntity || !zipEntity->zs) {
924             return NapiBusinessError(EFAULT, true);
925         }
926         arg->errCode = deflatePrime(zipEntity->zs.get(), bits, value);
927         if (arg->errCode < 0) {
928             return NapiBusinessError(arg->errCode, true);
929         }
930         return NapiBusinessError(ERRNO_NOERR);
931     };
932 
933     auto cbCompl = [arg](napi_env env, NapiBusinessError err) -> NapiValue {
934         if (err) {
935             return {env, err.GetNapiErr(env)};
936         }
937         if (!arg) {
938             return {NapiValue::CreateUndefined(env)};
939         }
940         return {NapiValue::CreateInt32(env, arg->errCode)};
941     };
942 
943     NapiValue thisVar(env, funcArg.GetThisVar());
944     if (funcArg.GetArgc() == ArgumentCount::THREE) {
945         return NapiAsyncWorkPromise(env, thisVar).Schedule(PROCEDURE_ZIP_NAME, cbExec, cbCompl).val_;
946     }
947 
948     return NapiValue::CreateUndefined(env).val_;
949 }
950 
DeflateTune(napi_env env,napi_callback_info info)951 napi_value ZipNExporter::DeflateTune(napi_env env, napi_callback_info info)
952 {
953     NapiFuncArg funcArg(env, info);
954     if (!funcArg.InitArgs(ArgumentCount::FIVE, ArgumentCount::SIX)) {
955         NapiBusinessError().ThrowErr(env, EINVAL);
956         return nullptr;
957     }
958 
959     /* To get entity */
960     auto zipEntity = NapiClass::GetEntityOf<ZipEntity>(env, funcArg.GetThisVar());
961     if (!zipEntity) {
962         NapiBusinessError().ThrowErr(env, EFAULT);
963         return nullptr;
964     }
965 
966     bool succ = false;
967     int32_t goodLength = 0;
968     int32_t maxLazy = 0;
969     int32_t niceLength = 0;
970     int32_t maxChain = 0;
971     tie(succ, goodLength, maxLazy, niceLength, maxChain) = CommonFunc::UnwrapDeflateTuneParams(env, funcArg);
972     if (!succ) {
973         return nullptr;
974     }
975 
976     auto arg = make_shared<AsyncZipArg>();
977     auto cbExec = [arg, zipEntity, goodLength, maxLazy, niceLength, maxChain](napi_env env) -> NapiBusinessError {
978         if (!arg || !zipEntity || !zipEntity->zs) {
979             return NapiBusinessError(EFAULT, true);
980         }
981         arg->errCode = deflateTune(zipEntity->zs.get(), goodLength, maxLazy, niceLength, maxChain);
982         if (arg->errCode < 0) {
983             return NapiBusinessError(arg->errCode, true);
984         }
985         return NapiBusinessError(ERRNO_NOERR);
986     };
987 
988     auto cbCompl = [arg](napi_env env, NapiBusinessError err) -> NapiValue {
989         if (err) {
990             return {env, err.GetNapiErr(env)};
991         }
992         if (!arg) {
993             return {NapiValue::CreateUndefined(env)};
994         }
995         return {NapiValue::CreateInt32(env, arg->errCode)};
996     };
997 
998     NapiValue thisVar(env, funcArg.GetThisVar());
999     if (funcArg.GetArgc() == ArgumentCount::FIVE) {
1000         return NapiAsyncWorkPromise(env, thisVar).Schedule(PROCEDURE_ZIP_NAME, cbExec, cbCompl).val_;
1001     }
1002 
1003     return NapiValue::CreateUndefined(env).val_;
1004 }
1005 
DeflateSetDictionary(napi_env env,napi_callback_info info)1006 napi_value ZipNExporter::DeflateSetDictionary(napi_env env, napi_callback_info info)
1007 {
1008     NapiFuncArg funcArg(env, info);
1009     if (!funcArg.InitArgs(ArgumentCount::TWO, ArgumentCount::THREE)) {
1010         NapiBusinessError().ThrowErr(env, EINVAL);
1011         return nullptr;
1012     }
1013 
1014     /* To get entity */
1015     auto zipEntity = NapiClass::GetEntityOf<ZipEntity>(env, funcArg.GetThisVar());
1016     if (!zipEntity) {
1017         NapiBusinessError().ThrowErr(env, EFAULT);
1018         return nullptr;
1019     }
1020 
1021     bool succ = false;
1022     void *dictionary = nullptr;
1023     size_t dictionaryLen = 0;
1024     tie(succ, dictionary, dictionaryLen) = CommonFunc::UnwrapArrayBufferParams(env, funcArg);
1025     if (!succ) {
1026         return nullptr;
1027     }
1028 
1029     auto arg = make_shared<AsyncZipArg>();
1030     auto cbExec = [arg, zipEntity, dictionary, dictionaryLen](napi_env env) -> NapiBusinessError {
1031         if (!arg || !zipEntity || !zipEntity->zs) {
1032             return NapiBusinessError(EFAULT, true);
1033         }
1034         arg->errCode = deflateSetDictionary(
1035             zipEntity->zs.get(), reinterpret_cast<const Bytef *>(dictionary), static_cast<uInt>(dictionaryLen));
1036         if (arg->errCode < 0) {
1037             return NapiBusinessError(arg->errCode, true);
1038         }
1039         return NapiBusinessError(ERRNO_NOERR);
1040     };
1041 
1042     auto cbCompl = [arg](napi_env env, NapiBusinessError err) -> NapiValue {
1043         if (err) {
1044             return {env, err.GetNapiErr(env)};
1045         }
1046         if (!arg) {
1047             return {NapiValue::CreateUndefined(env)};
1048         }
1049         return {NapiValue::CreateInt32(env, arg->errCode)};
1050     };
1051 
1052     NapiValue thisVar(env, funcArg.GetThisVar());
1053     if (funcArg.GetArgc() == ArgumentCount::TWO) {
1054         return NapiAsyncWorkPromise(env, thisVar).Schedule(PROCEDURE_ZIP_NAME, cbExec, cbCompl).val_;
1055     }
1056 
1057     return NapiValue::CreateUndefined(env).val_;
1058 }
1059 
DeflateGetDictionary(napi_env env,napi_callback_info info)1060 napi_value ZipNExporter::DeflateGetDictionary(napi_env env, napi_callback_info info)
1061 {
1062     NapiFuncArg funcArg(env, info);
1063     if (!funcArg.InitArgs(ArgumentCount::TWO, ArgumentCount::THREE)) {
1064         NapiBusinessError().ThrowErr(env, EINVAL);
1065         return nullptr;
1066     }
1067 
1068     /* To get entity */
1069     auto zipEntity = NapiClass::GetEntityOf<ZipEntity>(env, funcArg.GetThisVar());
1070     if (!zipEntity) {
1071         NapiBusinessError().ThrowErr(env, EFAULT);
1072         return nullptr;
1073     }
1074 
1075     bool succ = false;
1076     void *dictionary = nullptr;
1077     auto arg = make_shared<AsyncZipArg>();
1078     tie(succ, dictionary, arg->dictLength) = CommonFunc::UnwrapArrayBufferParams(env, funcArg);
1079 
1080     auto cbExec = [arg, zipEntity, dictionary](napi_env env) -> NapiBusinessError {
1081         if (!arg || !zipEntity || !zipEntity->zs) {
1082             return NapiBusinessError(EFAULT, true);
1083         }
1084         arg->errCode = deflateGetDictionary(zipEntity->zs.get(), static_cast<Bytef *>(dictionary), &arg->dictLength);
1085         if (arg->errCode < 0) {
1086             return NapiBusinessError(arg->errCode, true);
1087         }
1088         return NapiBusinessError(ERRNO_NOERR);
1089     };
1090 
1091     auto cbCompl = [arg](napi_env env, NapiBusinessError err) -> NapiValue {
1092         if (err) {
1093             return {env, err.GetNapiErr(env)};
1094         }
1095         if (!arg) {
1096             return {NapiValue::CreateUndefined(env)};
1097         }
1098 
1099         NapiValue obj = DictionaryOutputInfo(env, arg);
1100         return {obj};
1101     };
1102 
1103     NapiValue thisVar(env, funcArg.GetThisVar());
1104     if (funcArg.GetArgc() == ArgumentCount::TWO) {
1105         return NapiAsyncWorkPromise(env, thisVar).Schedule(PROCEDURE_ZIP_NAME, cbExec, cbCompl).val_;
1106     }
1107 
1108     return NapiValue::CreateUndefined(env).val_;
1109 }
1110 
DeflateSetHeader(napi_env env,napi_callback_info info)1111 napi_value ZipNExporter::DeflateSetHeader(napi_env env, napi_callback_info info)
1112 {
1113     NapiFuncArg funcArg(env, info);
1114     if (!funcArg.InitArgs(ArgumentCount::TWO, ArgumentCount::THREE)) {
1115         NapiBusinessError().ThrowErr(env, EINVAL);
1116         return nullptr;
1117     }
1118 
1119     /* To get entity */
1120     auto zipEntity = NapiClass::GetEntityOf<ZipEntity>(env, funcArg.GetThisVar());
1121     if (!zipEntity) {
1122         NapiBusinessError().ThrowErr(env, EFAULT);
1123         return nullptr;
1124     }
1125 
1126     bool succ = CommonFunc::SetZStreamValue(env, funcArg);
1127     if (!succ) {
1128         return nullptr;
1129     }
1130 
1131     gz_header gzHeader = {};
1132     tie(succ, gzHeader) = CommonFunc::GetGZHeaderArg(env, funcArg[ArgumentPosition::SECOND]);
1133     if (!succ) {
1134         return nullptr;
1135     }
1136 
1137     auto arg = make_shared<AsyncZipArg>();
1138     auto cbExec = [arg, zipEntity, gzHeader](napi_env env) -> NapiBusinessError {
1139         if (!arg || !zipEntity || !zipEntity->zs) {
1140             return NapiBusinessError(EFAULT, true);
1141         }
1142         arg->errCode = deflateSetHeader(zipEntity->zs.get(), const_cast<gz_headerp>(&gzHeader));
1143         if (arg->errCode < 0) {
1144             return NapiBusinessError(arg->errCode, true);
1145         }
1146         return NapiBusinessError(ERRNO_NOERR);
1147     };
1148 
1149     auto cbCompl = [arg](napi_env env, NapiBusinessError err) -> NapiValue {
1150         if (err) {
1151             return {env, err.GetNapiErr(env)};
1152         }
1153         if (!arg) {
1154             return {NapiValue::CreateUndefined(env)};
1155         }
1156         return {NapiValue::CreateInt32(env, arg->errCode)};
1157     };
1158 
1159     NapiValue thisVar(env, funcArg.GetThisVar());
1160     if (funcArg.GetArgc() == ArgumentCount::TWO) {
1161         return NapiAsyncWorkPromise(env, thisVar).Schedule(PROCEDURE_ZIP_NAME, cbExec, cbCompl).val_;
1162     }
1163 
1164     return NapiValue::CreateUndefined(env).val_;
1165 }
1166 
DeflatePending(napi_env env,napi_callback_info info)1167 napi_value ZipNExporter::DeflatePending(napi_env env, napi_callback_info info)
1168 {
1169     NapiFuncArg funcArg(env, info);
1170     if (!funcArg.InitArgs(ArgumentCount::ONE, ArgumentCount::TWO)) {
1171         NapiBusinessError().ThrowErr(env, EINVAL);
1172         return nullptr;
1173     }
1174 
1175     /* To get entity */
1176     auto zipEntity = NapiClass::GetEntityOf<ZipEntity>(env, funcArg.GetThisVar());
1177     if (!zipEntity) {
1178         NapiBusinessError().ThrowErr(env, EFAULT);
1179         return nullptr;
1180     }
1181 
1182     bool succ = CommonFunc::SetZStreamValue(env, funcArg);
1183     if (!succ) {
1184         return nullptr;
1185     }
1186 
1187     auto arg = make_shared<AsyncZipArg>();
1188     auto cbExec = [arg, zipEntity](napi_env env) -> NapiBusinessError {
1189         if (!arg || !zipEntity || !zipEntity->zs) {
1190             return NapiBusinessError(EFAULT, true);
1191         }
1192         arg->errCode = deflatePending(zipEntity->zs.get(), &arg->pending, &arg->bits);
1193         if (arg->errCode < 0) {
1194             return NapiBusinessError(arg->errCode, true);
1195         }
1196         return NapiBusinessError(ERRNO_NOERR);
1197     };
1198 
1199     auto cbCompl = [arg](napi_env env, NapiBusinessError err) -> NapiValue {
1200         if (err) {
1201             return {env, err.GetNapiErr(env)};
1202         }
1203         if (!arg) {
1204             return {NapiValue::CreateUndefined(env)};
1205         }
1206         NapiValue obj = DeflatePendingOutputInfo(env, arg);
1207         return {obj};
1208     };
1209 
1210     NapiValue thisVar(env, funcArg.GetThisVar());
1211     if (funcArg.GetArgc() == ArgumentCount::ONE) {
1212         return NapiAsyncWorkPromise(env, thisVar).Schedule(PROCEDURE_ZIP_NAME, cbExec, cbCompl).val_;
1213     }
1214 
1215     return NapiValue::CreateUndefined(env).val_;
1216 }
1217 
DeflateCopy(napi_env env,napi_callback_info info)1218 napi_value ZipNExporter::DeflateCopy(napi_env env, napi_callback_info info)
1219 {
1220     NapiFuncArg funcArg(env, info);
1221     if (!funcArg.InitArgs(ArgumentCount::ONE, ArgumentCount::TWO)) {
1222         NapiBusinessError().ThrowErr(env, EINVAL);
1223         return nullptr;
1224     }
1225 
1226     /* To get entity */
1227     auto zipEntity = NapiClass::GetEntityOf<ZipEntity>(env, funcArg.GetThisVar());
1228     if (!zipEntity) {
1229         NapiBusinessError().ThrowErr(env, EFAULT);
1230         return nullptr;
1231     }
1232 
1233     auto srcZipEntity = NapiClass::GetEntityOf<ZipEntity>(env, funcArg[ArgumentPosition::FIRST]);
1234     if (!srcZipEntity) {
1235         NapiBusinessError().ThrowErr(env, EINVAL);
1236         return nullptr;
1237     }
1238 
1239     auto arg = make_shared<AsyncZipArg>();
1240     auto cbExec = [arg, zipEntity, srcZipEntity](napi_env env) -> NapiBusinessError {
1241         if (!arg || !zipEntity || !srcZipEntity) {
1242             return NapiBusinessError(EFAULT, true);
1243         }
1244 
1245         if (!zipEntity->zs) {
1246             std::unique_ptr<z_stream> zs = std::make_unique<z_stream>();
1247             zipEntity->zs.swap(zs);
1248         }
1249         arg->errCode = deflateCopy(zipEntity->zs.get(), srcZipEntity->zs.get());
1250         if (arg->errCode < 0) {
1251             return NapiBusinessError(arg->errCode, true);
1252         }
1253         return NapiBusinessError(ERRNO_NOERR);
1254     };
1255 
1256     auto cbCompl = [arg](napi_env env, NapiBusinessError err) -> NapiValue {
1257         if (err) {
1258             return {env, err.GetNapiErr(env)};
1259         }
1260         if (!arg) {
1261             return {NapiValue::CreateUndefined(env)};
1262         }
1263         return {NapiValue::CreateInt32(env, arg->errCode)};
1264     };
1265 
1266     NapiValue thisVar(env, funcArg.GetThisVar());
1267     if (funcArg.GetArgc() == ArgumentCount::ONE) {
1268         return NapiAsyncWorkPromise(env, thisVar).Schedule(PROCEDURE_ZIP_NAME, cbExec, cbCompl).val_;
1269     }
1270 
1271     return NapiValue::CreateUndefined(env).val_;
1272 }
1273 
Compress(napi_env env,napi_callback_info info)1274 napi_value ZipNExporter::Compress(napi_env env, napi_callback_info info)
1275 {
1276     NapiFuncArg funcArg(env, info);
1277     if (!funcArg.InitArgs(ArgumentCount::TWO, ArgumentCount::THREE)) {
1278         NapiBusinessError().ThrowErr(env, EINVAL);
1279         return nullptr;
1280     }
1281 
1282     /* To get entity */
1283     auto zipEntity = NapiClass::GetEntityOf<ZipEntity>(env, funcArg.GetThisVar());
1284     if (!zipEntity) {
1285         NapiBusinessError().ThrowErr(env, EFAULT);
1286         return nullptr;
1287     }
1288 
1289     bool succ = false;
1290     void *dest = nullptr;
1291     void *source = nullptr;
1292     auto arg = make_shared<AsyncZipArg>();
1293     tie(succ, dest, arg->destLen, source, arg->sourceLen) = CommonFunc::GetCompressArg(env, funcArg);
1294     if (!succ) {
1295         return nullptr;
1296     }
1297 
1298     auto cbExec = [arg, dest, source](napi_env env) -> NapiBusinessError {
1299         if (!arg) {
1300             return NapiBusinessError(EFAULT, true);
1301         }
1302         if (!source || !dest) {
1303             return NapiBusinessError(ERROR_CODE, true);
1304         }
1305         arg->errCode =
1306             compress(reinterpret_cast<Bytef *>(dest), &arg->destLen, reinterpret_cast<Bytef *>(source), arg->sourceLen);
1307         if (arg->errCode < 0) {
1308             return NapiBusinessError(arg->errCode, true);
1309         }
1310         return NapiBusinessError(ERRNO_NOERR);
1311     };
1312 
1313     auto cbCompl = [arg](napi_env env, NapiBusinessError err) -> NapiValue {
1314         if (err) {
1315             return {env, err.GetNapiErr(env)};
1316         }
1317         if (!arg) {
1318             return {NapiValue::CreateUndefined(env)};
1319         }
1320         NapiValue obj = ZipOutputInfo(env, arg);
1321         return {obj};
1322     };
1323 
1324     NapiValue thisVar(env, funcArg.GetThisVar());
1325     if (funcArg.GetArgc() == ArgumentCount::TWO || funcArg.GetArgc() == ArgumentCount::THREE) {
1326         return NapiAsyncWorkPromise(env, thisVar).Schedule(PROCEDURE_ZIP_NAME, cbExec, cbCompl).val_;
1327     }
1328 
1329     return NapiValue::CreateUndefined(env).val_;
1330 }
1331 
Compress2(napi_env env,napi_callback_info info)1332 napi_value ZipNExporter::Compress2(napi_env env, napi_callback_info info)
1333 {
1334     NapiFuncArg funcArg(env, info);
1335     if (!funcArg.InitArgs(ArgumentCount::THREE, ArgumentCount::FOUR)) {
1336         NapiBusinessError().ThrowErr(env, EINVAL);
1337         return nullptr;
1338     }
1339 
1340     /* To get entity */
1341     auto zipEntity = NapiClass::GetEntityOf<ZipEntity>(env, funcArg.GetThisVar());
1342     if (!zipEntity) {
1343         NapiBusinessError().ThrowErr(env, EFAULT);
1344         return nullptr;
1345     }
1346 
1347     bool succ = false;
1348     void *dest = nullptr;
1349     void *source = nullptr;
1350     auto arg = make_shared<AsyncZipArg>();
1351     tie(succ, dest, arg->destLen, source, arg->sourceLen, arg->level) = CommonFunc::GetCompress2Arg(env, funcArg);
1352     if (!succ) {
1353         return nullptr;
1354     }
1355 
1356     auto cbExec = [arg, dest, source](napi_env env) -> NapiBusinessError {
1357         if (!arg) {
1358             return NapiBusinessError(EFAULT, true);
1359         }
1360         if (!source || !dest) {
1361             return NapiBusinessError(ERROR_CODE, true);
1362         }
1363         arg->errCode = compress2(
1364             static_cast<Bytef *>(dest), &arg->destLen, static_cast<Bytef *>(source), arg->sourceLen, arg->level);
1365         if (arg->errCode < 0) {
1366             return NapiBusinessError(arg->errCode, true);
1367         }
1368         return NapiBusinessError(ERRNO_NOERR);
1369     };
1370 
1371     auto cbCompl = [arg](napi_env env, NapiBusinessError err) -> NapiValue {
1372         if (err) {
1373             return {env, err.GetNapiErr(env)};
1374         }
1375         if (!arg) {
1376             return {NapiValue::CreateUndefined(env)};
1377         }
1378         NapiValue obj = ZipOutputInfo(env, arg);
1379         return {obj};
1380     };
1381 
1382     NapiValue thisVar(env, funcArg.GetThisVar());
1383     if (funcArg.GetArgc() == ArgumentCount::THREE || funcArg.GetArgc() == ArgumentCount::FOUR) {
1384         return NapiAsyncWorkPromise(env, thisVar).Schedule(PROCEDURE_ZIP_NAME, cbExec, cbCompl).val_;
1385     }
1386 
1387     return NapiValue::CreateUndefined(env).val_;
1388 }
1389 
CompressBound(napi_env env,napi_callback_info info)1390 napi_value ZipNExporter::CompressBound(napi_env env, napi_callback_info info)
1391 {
1392     NapiFuncArg funcArg(env, info);
1393     if (!funcArg.InitArgs(ArgumentCount::ONE, ArgumentCount::TWO)) {
1394         NapiBusinessError().ThrowErr(env, EINVAL);
1395         return nullptr;
1396     }
1397 
1398     int32_t sourceLen = 0;
1399     bool succ = false;
1400     tie(succ, sourceLen) = CommonFunc::UnwrapInt32Params(env, funcArg[ArgumentPosition::FIRST]);
1401     if (!succ) {
1402         return nullptr;
1403     }
1404 
1405     auto arg = make_shared<AsyncZipArg>();
1406     auto cbExec = [arg, sourceLen](napi_env env) -> NapiBusinessError {
1407         if (!arg) {
1408             return NapiBusinessError(EFAULT, true);
1409         }
1410         arg->errCode = static_cast<int32_t>(compressBound(sourceLen));
1411         return NapiBusinessError(ERRNO_NOERR);
1412     };
1413 
1414     auto cbCompl = [arg](napi_env env, NapiBusinessError err) -> NapiValue {
1415         if (err) {
1416             return {env, err.GetNapiErr(env)};
1417         }
1418         if (!arg) {
1419             return {NapiValue::CreateUndefined(env)};
1420         }
1421         return {NapiValue::CreateInt32(env, arg->errCode)};
1422     };
1423 
1424     NapiValue thisVar(env, funcArg.GetThisVar());
1425     if (funcArg.GetArgc() == ArgumentCount::ONE) {
1426         return NapiAsyncWorkPromise(env, thisVar).Schedule(PROCEDURE_ZIP_NAME, cbExec, cbCompl).val_;
1427     }
1428 
1429     return NapiValue::CreateUndefined(env).val_;
1430 }
1431 
UnCompress(napi_env env,napi_callback_info info)1432 napi_value ZipNExporter::UnCompress(napi_env env, napi_callback_info info)
1433 {
1434     NapiFuncArg funcArg(env, info);
1435     if (!funcArg.InitArgs(ArgumentCount::TWO, ArgumentCount::THREE)) {
1436         NapiBusinessError().ThrowErr(env, EINVAL);
1437         return nullptr;
1438     }
1439 
1440     /* To get entity */
1441     auto zipEntity = NapiClass::GetEntityOf<ZipEntity>(env, funcArg.GetThisVar());
1442     if (!zipEntity) {
1443         NapiBusinessError().ThrowErr(env, EFAULT);
1444         return nullptr;
1445     }
1446 
1447     bool succ = false;
1448     void *dest = nullptr;
1449     void *source = nullptr;
1450     auto arg = make_shared<AsyncZipArg>();
1451     tie(succ, dest, arg->destLen, source, arg->sourceLen) = CommonFunc::GetUnCompressArg(env, funcArg);
1452     if (!succ) {
1453         return nullptr;
1454     }
1455 
1456     auto cbExec = [arg, dest, source](napi_env env) -> NapiBusinessError {
1457         if (!arg) {
1458             return NapiBusinessError(EFAULT, true);
1459         }
1460         if (!source || !dest) {
1461             return NapiBusinessError(ERROR_CODE, true);
1462         }
1463         arg->errCode =
1464             uncompress(static_cast<Bytef *>(dest), &arg->destLen, static_cast<Bytef *>(source), arg->sourceLen);
1465         if (arg->errCode < 0) {
1466             return NapiBusinessError(arg->errCode, true);
1467         }
1468         return NapiBusinessError(ERRNO_NOERR);
1469     };
1470 
1471     auto cbCompl = [arg](napi_env env, NapiBusinessError err) -> NapiValue {
1472         if (err) {
1473             return {env, err.GetNapiErr(env)};
1474         }
1475         if (!arg) {
1476             return {NapiValue::CreateUndefined(env)};
1477         }
1478         NapiValue obj = ZipOutputInfo(env, arg);
1479         return {obj};
1480     };
1481 
1482     NapiValue thisVar(env, funcArg.GetThisVar());
1483     if (funcArg.GetArgc() == ArgumentCount::TWO || funcArg.GetArgc() == ArgumentCount::THREE) {
1484         return NapiAsyncWorkPromise(env, thisVar).Schedule(PROCEDURE_ZIP_NAME, cbExec, cbCompl).val_;
1485     }
1486 
1487     return NapiValue::CreateUndefined(env).val_;
1488 }
1489 
UnCompress2(napi_env env,napi_callback_info info)1490 napi_value ZipNExporter::UnCompress2(napi_env env, napi_callback_info info)
1491 {
1492     NapiFuncArg funcArg(env, info);
1493     if (!funcArg.InitArgs(ArgumentCount::TWO, ArgumentCount::THREE)) {
1494         NapiBusinessError().ThrowErr(env, EINVAL);
1495         return nullptr;
1496     }
1497 
1498     /* To get entity */
1499     auto zipEntity = NapiClass::GetEntityOf<ZipEntity>(env, funcArg.GetThisVar());
1500     if (!zipEntity) {
1501         NapiBusinessError().ThrowErr(env, EFAULT);
1502         return nullptr;
1503     }
1504 
1505     bool succ = false;
1506     void *dest = nullptr;
1507     void *source = nullptr;
1508     auto arg = make_shared<AsyncZipArg>();
1509     tie(succ, dest, arg->destLen, source, arg->sourceLen) = CommonFunc::GetUnCompressArg(env, funcArg);
1510     if (!succ) {
1511         return nullptr;
1512     }
1513 
1514     auto cbExec = [arg, dest, source](napi_env env) -> NapiBusinessError {
1515         if (!arg) {
1516             return NapiBusinessError(EFAULT, true);
1517         }
1518         if (!source || !dest) {
1519             return NapiBusinessError(ERROR_CODE, true);
1520         }
1521         arg->errCode =
1522             uncompress2(static_cast<Bytef *>(dest), &arg->destLen, static_cast<Bytef *>(source), &arg->sourceLen);
1523         if (arg->errCode < 0) {
1524             return NapiBusinessError(arg->errCode, true);
1525         }
1526         return NapiBusinessError(ERRNO_NOERR);
1527     };
1528 
1529     auto cbCompl = [arg](napi_env env, NapiBusinessError err) -> NapiValue {
1530         if (err) {
1531             return {env, err.GetNapiErr(env)};
1532         }
1533         if (!arg) {
1534             return {NapiValue::CreateUndefined(env)};
1535         }
1536         NapiValue obj = DecompressionOutputInfo(env, arg);
1537         return {obj};
1538     };
1539 
1540     NapiValue thisVar(env, funcArg.GetThisVar());
1541     if (funcArg.GetArgc() == ArgumentCount::TWO || funcArg.GetArgc() == ArgumentCount::THREE) {
1542         return NapiAsyncWorkPromise(env, thisVar).Schedule(PROCEDURE_ZIP_NAME, cbExec, cbCompl).val_;
1543     }
1544 
1545     return NapiValue::CreateUndefined(env).val_;
1546 }
1547 
InflateInit(napi_env env,napi_callback_info info)1548 napi_value ZipNExporter::InflateInit(napi_env env, napi_callback_info info)
1549 {
1550     NapiFuncArg funcArg(env, info);
1551     if (!funcArg.InitArgs(ArgumentCount::ONE, ArgumentCount::TWO)) {
1552         NapiBusinessError().ThrowErr(env, EINVAL);
1553         return nullptr;
1554     }
1555 
1556     /* To get entity */
1557     auto zipEntity = NapiClass::GetEntityOf<ZipEntity>(env, funcArg.GetThisVar());
1558     if (!zipEntity) {
1559         NapiBusinessError().ThrowErr(env, EFAULT);
1560         return nullptr;
1561     }
1562 
1563     bool succ = false;
1564     z_stream zStream = {};
1565     HasZStreamMember hasZStreamMember = {};
1566     tie(succ, zStream, hasZStreamMember) = CommonFunc::GetZstreamArg(env, funcArg[ArgumentPosition::FIRST]);
1567     if (!succ) {
1568         return nullptr;
1569     }
1570 
1571     auto arg = make_shared<AsyncZipArg>();
1572     auto cbExec = [arg, zipEntity, zStream](napi_env env) -> NapiBusinessError {
1573         if (!arg || !zipEntity) {
1574             return NapiBusinessError(EFAULT, true);
1575         }
1576         std::unique_ptr<z_stream> zs = std::make_unique<z_stream>(zStream);
1577         arg->errCode = inflateInit(zs.get());
1578         if (arg->errCode < 0) {
1579             return NapiBusinessError(arg->errCode, true);
1580         }
1581         zipEntity->zs.swap(zs);
1582         return NapiBusinessError(ERRNO_NOERR);
1583     };
1584 
1585     auto cbCompl = [arg](napi_env env, NapiBusinessError err) -> NapiValue {
1586         if (err) {
1587             return {env, err.GetNapiErr(env)};
1588         }
1589         if (!arg) {
1590             return {NapiValue::CreateUndefined(env)};
1591         }
1592         return {NapiValue::CreateInt32(env, arg->errCode)};
1593     };
1594 
1595     NapiValue thisVar(env, funcArg.GetThisVar());
1596     if (funcArg.GetArgc() == ArgumentCount::ONE) {
1597         return NapiAsyncWorkPromise(env, thisVar).Schedule(PROCEDURE_ZIP_NAME, cbExec, cbCompl).val_;
1598     }
1599 
1600     return NapiValue::CreateUndefined(env).val_;
1601 }
1602 
InflateInit2(napi_env env,napi_callback_info info)1603 napi_value ZipNExporter::InflateInit2(napi_env env, napi_callback_info info)
1604 {
1605     NapiFuncArg funcArg(env, info);
1606     if (!funcArg.InitArgs(ArgumentCount::TWO, ArgumentCount::THREE)) {
1607         NapiBusinessError().ThrowErr(env, EINVAL);
1608         return nullptr;
1609     }
1610 
1611     /* To get entity */
1612     auto zipEntity = NapiClass::GetEntityOf<ZipEntity>(env, funcArg.GetThisVar());
1613     if (!zipEntity) {
1614         NapiBusinessError().ThrowErr(env, EFAULT);
1615         return nullptr;
1616     }
1617 
1618     bool succ = false;
1619     z_stream zStream = {};
1620     int32_t windowBits = 0;
1621     tie(succ, zStream, windowBits) = CommonFunc::GetInflateInitArg(env, funcArg);
1622     if (!succ) {
1623         return nullptr;
1624     }
1625 
1626     auto arg = make_shared<AsyncZipArg>();
1627     auto cbExec = [arg, zipEntity, zStream, windowBits](napi_env env) -> NapiBusinessError {
1628         if (!arg || !zipEntity) {
1629             return NapiBusinessError(EFAULT, true);
1630         }
1631         std::unique_ptr<z_stream> zs = std::make_unique<z_stream>(zStream);
1632         arg->errCode = inflateInit2(zs.get(), windowBits);
1633         if (arg->errCode < 0) {
1634             return NapiBusinessError(arg->errCode, true);
1635         }
1636         zipEntity->zs.swap(zs);
1637         return NapiBusinessError(ERRNO_NOERR);
1638     };
1639 
1640     auto cbCompl = [arg](napi_env env, NapiBusinessError err) -> NapiValue {
1641         if (err) {
1642             return {env, err.GetNapiErr(env)};
1643         }
1644         if (!arg) {
1645             return {NapiValue::CreateUndefined(env)};
1646         }
1647         return {NapiValue::CreateInt32(env, arg->errCode)};
1648     };
1649 
1650     NapiValue thisVar(env, funcArg.GetThisVar());
1651     if (funcArg.GetArgc() == ArgumentCount::TWO) {
1652         return NapiAsyncWorkPromise(env, thisVar).Schedule(PROCEDURE_ZIP_NAME, cbExec, cbCompl).val_;
1653     }
1654 
1655     return NapiValue::CreateUndefined(env).val_;
1656 }
1657 
InflateSync(napi_env env,napi_callback_info info)1658 napi_value ZipNExporter::InflateSync(napi_env env, napi_callback_info info)
1659 {
1660     NapiFuncArg funcArg(env, info);
1661     if (!funcArg.InitArgs(ArgumentCount::ONE, ArgumentCount::TWO)) {
1662         NapiBusinessError().ThrowErr(env, EINVAL);
1663         return nullptr;
1664     }
1665 
1666     /* To get entity */
1667     auto zipEntity = NapiClass::GetEntityOf<ZipEntity>(env, funcArg.GetThisVar());
1668     if (!zipEntity) {
1669         NapiBusinessError().ThrowErr(env, EFAULT);
1670         return nullptr;
1671     }
1672 
1673     bool succ = CommonFunc::SetZStreamValue(env, funcArg);
1674     if (!succ) {
1675         return nullptr;
1676     }
1677 
1678     auto arg = make_shared<AsyncZipArg>();
1679     auto cbExec = [arg, zipEntity](napi_env env) -> NapiBusinessError {
1680         if (!arg || !zipEntity || !zipEntity->zs) {
1681             return NapiBusinessError(EFAULT, true);
1682         }
1683         arg->errCode = inflateSync(zipEntity->zs.get());
1684         if (arg->errCode < 0) {
1685             return NapiBusinessError(arg->errCode, true);
1686         }
1687         return NapiBusinessError(ERRNO_NOERR);
1688     };
1689 
1690     auto cbCompl = [arg](napi_env env, NapiBusinessError err) -> NapiValue {
1691         if (err) {
1692             return {env, err.GetNapiErr(env)};
1693         }
1694         if (!arg) {
1695             return {NapiValue::CreateUndefined(env)};
1696         }
1697         return {NapiValue::CreateInt32(env, arg->errCode)};
1698     };
1699 
1700     NapiValue thisVar(env, funcArg.GetThisVar());
1701     if (funcArg.GetArgc() == ArgumentCount::ONE) {
1702         return NapiAsyncWorkPromise(env, thisVar).Schedule(PROCEDURE_ZIP_NAME, cbExec, cbCompl).val_;
1703     }
1704 
1705     return NapiValue::CreateUndefined(env).val_;
1706 }
1707 
Inflate(napi_env env,napi_callback_info info)1708 napi_value ZipNExporter::Inflate(napi_env env, napi_callback_info info)
1709 {
1710     NapiFuncArg funcArg(env, info);
1711     if (!funcArg.InitArgs(ArgumentCount::TWO, ArgumentCount::THREE)) {
1712         NapiBusinessError().ThrowErr(env, EINVAL);
1713         return nullptr;
1714     }
1715 
1716     /* To get entity */
1717     auto zipEntity = NapiClass::GetEntityOf<ZipEntity>(env, funcArg.GetThisVar());
1718     if (!zipEntity) {
1719         NapiBusinessError().ThrowErr(env, EFAULT);
1720         return nullptr;
1721     }
1722 
1723     bool succ = false;
1724     int32_t flush = 0;
1725     tie(succ, flush) = CommonFunc::GetInflateArg(env, funcArg);
1726     if (!succ) {
1727         return nullptr;
1728     }
1729 
1730     auto arg = make_shared<AsyncZipArg>();
1731     auto cbExec = [arg, zipEntity, flush](napi_env env) -> NapiBusinessError {
1732         if (!arg || !zipEntity || !zipEntity->zs) {
1733             return NapiBusinessError(EFAULT, true);
1734         }
1735         arg->errCode = inflate(zipEntity->zs.get(), flush);
1736         if (arg->errCode < 0) {
1737             return NapiBusinessError(arg->errCode, true);
1738         }
1739         return NapiBusinessError(ERRNO_NOERR);
1740     };
1741 
1742     auto cbCompl = [arg](napi_env env, NapiBusinessError err) -> NapiValue {
1743         if (err) {
1744             return {env, err.GetNapiErr(env)};
1745         }
1746         if (!arg) {
1747             return {NapiValue::CreateUndefined(env)};
1748         }
1749         return {NapiValue::CreateInt32(env, arg->errCode)};
1750     };
1751 
1752     NapiValue thisVar(env, funcArg.GetThisVar());
1753     if (funcArg.GetArgc() == ArgumentCount::TWO) {
1754         return NapiAsyncWorkPromise(env, thisVar).Schedule(PROCEDURE_ZIP_NAME, cbExec, cbCompl).val_;
1755     }
1756 
1757     return NapiValue::CreateUndefined(env).val_;
1758 }
1759 
InflateEnd(napi_env env,napi_callback_info info)1760 napi_value ZipNExporter::InflateEnd(napi_env env, napi_callback_info info)
1761 {
1762     NapiFuncArg funcArg(env, info);
1763     if (!funcArg.InitArgs(ArgumentCount::ONE, ArgumentCount::TWO)) {
1764         NapiBusinessError().ThrowErr(env, EINVAL);
1765         return nullptr;
1766     }
1767 
1768     /* To get entity */
1769     auto zipEntity = NapiClass::GetEntityOf<ZipEntity>(env, funcArg.GetThisVar());
1770     if (!zipEntity) {
1771         NapiBusinessError().ThrowErr(env, EFAULT);
1772         return nullptr;
1773     }
1774 
1775     bool succ = CommonFunc::SetZStreamValue(env, funcArg);
1776     if (!succ) {
1777         return nullptr;
1778     }
1779 
1780     auto arg = make_shared<AsyncZipArg>();
1781     auto cbExec = [arg, zipEntity](napi_env env) -> NapiBusinessError {
1782         if (!arg || !zipEntity || !zipEntity->zs) {
1783             return NapiBusinessError(EFAULT, true);
1784         }
1785         arg->errCode = inflateEnd(zipEntity->zs.get());
1786         if (arg->errCode < 0) {
1787             return NapiBusinessError(arg->errCode, true);
1788         }
1789         return NapiBusinessError(ERRNO_NOERR);
1790     };
1791 
1792     auto cbCompl = [arg](napi_env env, NapiBusinessError err) -> NapiValue {
1793         if (err) {
1794             return {env, err.GetNapiErr(env)};
1795         }
1796         if (!arg) {
1797             return {NapiValue::CreateUndefined(env)};
1798         }
1799         return {NapiValue::CreateInt32(env, arg->errCode)};
1800     };
1801 
1802     NapiValue thisVar(env, funcArg.GetThisVar());
1803     if (funcArg.GetArgc() == ArgumentCount::ONE) {
1804         return NapiAsyncWorkPromise(env, thisVar).Schedule(PROCEDURE_ZIP_NAME, cbExec, cbCompl).val_;
1805     }
1806 
1807     return NapiValue::CreateUndefined(env).val_;
1808 }
1809 
InflateSetDictionary(napi_env env,napi_callback_info info)1810 napi_value ZipNExporter::InflateSetDictionary(napi_env env, napi_callback_info info)
1811 {
1812     NapiFuncArg funcArg(env, info);
1813     if (!funcArg.InitArgs(ArgumentCount::TWO, ArgumentCount::THREE)) {
1814         NapiBusinessError().ThrowErr(env, EINVAL);
1815         return nullptr;
1816     }
1817 
1818     /* To get entity */
1819     auto zipEntity = NapiClass::GetEntityOf<ZipEntity>(env, funcArg.GetThisVar());
1820     if (!zipEntity) {
1821         NapiBusinessError().ThrowErr(env, EFAULT);
1822         return nullptr;
1823     }
1824 
1825     bool succ = false;
1826     void *buf = nullptr;
1827     size_t bufLen = 0;
1828     tie(succ, buf, bufLen) = CommonFunc::GetInflateSetDictionaryArg(env, funcArg);
1829     if (!succ) {
1830         return nullptr;
1831     }
1832 
1833     auto arg = make_shared<AsyncZipArg>();
1834     auto cbExec = [arg, zipEntity, buf, bufLen](napi_env env) -> NapiBusinessError {
1835         if (!arg || !zipEntity || !zipEntity->zs) {
1836             return NapiBusinessError(EFAULT, true);
1837         }
1838         arg->errCode = inflateSetDictionary(zipEntity->zs.get(), static_cast<Bytef *>(buf), static_cast<uInt>(bufLen));
1839         if (arg->errCode < 0) {
1840             return NapiBusinessError(arg->errCode, true);
1841         }
1842         return NapiBusinessError(ERRNO_NOERR);
1843     };
1844 
1845     auto cbCompl = [arg](napi_env env, NapiBusinessError err) -> NapiValue {
1846         if (err) {
1847             return {env, err.GetNapiErr(env)};
1848         }
1849         if (!arg) {
1850             return {NapiValue::CreateUndefined(env)};
1851         }
1852         return {NapiValue::CreateInt32(env, arg->errCode)};
1853     };
1854 
1855     NapiValue thisVar(env, funcArg.GetThisVar());
1856     if (funcArg.GetArgc() == ArgumentCount::TWO) {
1857         return NapiAsyncWorkPromise(env, thisVar).Schedule(PROCEDURE_ZIP_NAME, cbExec, cbCompl).val_;
1858     }
1859 
1860     return NapiValue::CreateUndefined(env).val_;
1861 }
1862 
InflateGetDictionary(napi_env env,napi_callback_info info)1863 napi_value ZipNExporter::InflateGetDictionary(napi_env env, napi_callback_info info)
1864 {
1865     NapiFuncArg funcArg(env, info);
1866     if (!funcArg.InitArgs(ArgumentCount::TWO, ArgumentCount::THREE)) {
1867         NapiBusinessError().ThrowErr(env, EINVAL);
1868         return nullptr;
1869     }
1870 
1871     auto arg = make_shared<AsyncZipArg>();
1872     /* To get entity */
1873     auto zipEntity = NapiClass::GetEntityOf<ZipEntity>(env, funcArg.GetThisVar());
1874     if (!arg ||!zipEntity) {
1875         NapiBusinessError().ThrowErr(env, EFAULT);
1876         return nullptr;
1877     }
1878 
1879     bool succ = false;
1880     void *buf = nullptr;
1881     tie(succ, buf, arg->dictLength) = CommonFunc::GetInflateSetDictionaryArg(env, funcArg);
1882     if (!succ) {
1883         return nullptr;
1884     }
1885 
1886     auto cbExec = [arg, zipEntity, buf](napi_env env) -> NapiBusinessError {
1887         if (!arg || !zipEntity || !zipEntity->zs) {
1888             return NapiBusinessError(EFAULT, true);
1889         }
1890         arg->errCode = inflateGetDictionary(zipEntity->zs.get(), static_cast<Bytef *>(buf), &arg->dictLength);
1891         if (arg->errCode < 0) {
1892             return NapiBusinessError(arg->errCode, true);
1893         }
1894         return NapiBusinessError(ERRNO_NOERR);
1895     };
1896 
1897     auto cbCompl = [arg](napi_env env, NapiBusinessError err) -> NapiValue {
1898         if (err) {
1899             return {env, err.GetNapiErr(env)};
1900         }
1901         if (!arg) {
1902             return {NapiValue::CreateUndefined(env)};
1903         }
1904         NapiValue obj = DictionaryOutputInfo(env, arg);
1905         return {obj};
1906     };
1907 
1908     NapiValue thisVar(env, funcArg.GetThisVar());
1909     if (funcArg.GetArgc() == ArgumentCount::TWO) {
1910         return NapiAsyncWorkPromise(env, thisVar).Schedule(PROCEDURE_ZIP_NAME, cbExec, cbCompl).val_;
1911     }
1912 
1913     return NapiValue::CreateUndefined(env).val_;
1914 }
1915 
InflateResetKeep(napi_env env,napi_callback_info info)1916 napi_value ZipNExporter::InflateResetKeep(napi_env env, napi_callback_info info)
1917 {
1918     NapiFuncArg funcArg(env, info);
1919     if (!funcArg.InitArgs(ArgumentCount::ONE, ArgumentCount::TWO)) {
1920         NapiBusinessError().ThrowErr(env, EINVAL);
1921         return nullptr;
1922     }
1923 
1924     /* To get entity */
1925     auto zipEntity = NapiClass::GetEntityOf<ZipEntity>(env, funcArg.GetThisVar());
1926     if (!zipEntity) {
1927         NapiBusinessError().ThrowErr(env, EFAULT);
1928         return nullptr;
1929     }
1930 
1931     bool succ = CommonFunc::SetZStreamValue(env, funcArg);
1932     if (!succ) {
1933         return nullptr;
1934     }
1935 
1936     auto arg = make_shared<AsyncZipArg>();
1937     auto cbExec = [arg, zipEntity](napi_env env) -> NapiBusinessError {
1938         if (!arg || !zipEntity || !zipEntity->zs) {
1939             return NapiBusinessError(EFAULT, true);
1940         }
1941         arg->errCode = inflateResetKeep(zipEntity->zs.get());
1942         if (arg->errCode < 0) {
1943             return NapiBusinessError(arg->errCode, true);
1944         }
1945         return NapiBusinessError(ERRNO_NOERR);
1946     };
1947 
1948     auto cbCompl = [arg](napi_env env, NapiBusinessError err) -> NapiValue {
1949         if (err) {
1950             return {env, err.GetNapiErr(env)};
1951         }
1952         if (!arg) {
1953             return {NapiValue::CreateUndefined(env)};
1954         }
1955         return {NapiValue::CreateInt32(env, arg->errCode)};
1956     };
1957 
1958     NapiValue thisVar(env, funcArg.GetThisVar());
1959     if (funcArg.GetArgc() == ArgumentCount::ONE) {
1960         return NapiAsyncWorkPromise(env, thisVar).Schedule(PROCEDURE_ZIP_NAME, cbExec, cbCompl).val_;
1961     }
1962 
1963     return NapiValue::CreateUndefined(env).val_;
1964 }
1965 
InflateReset2(napi_env env,napi_callback_info info)1966 napi_value ZipNExporter::InflateReset2(napi_env env, napi_callback_info info)
1967 {
1968     NapiFuncArg funcArg(env, info);
1969     if (!funcArg.InitArgs(ArgumentCount::TWO, ArgumentCount::THREE)) {
1970         NapiBusinessError().ThrowErr(env, EINVAL);
1971         return nullptr;
1972     }
1973 
1974     /* To get entity */
1975     auto zipEntity = NapiClass::GetEntityOf<ZipEntity>(env, funcArg.GetThisVar());
1976     if (!zipEntity) {
1977         NapiBusinessError().ThrowErr(env, EFAULT);
1978         return nullptr;
1979     }
1980 
1981     bool succ = false;
1982     int32_t flush = 0;
1983     tie(succ, flush) = CommonFunc::GetInflateReset2Arg(env, funcArg);
1984     if (!succ) {
1985         return nullptr;
1986     }
1987 
1988     auto arg = make_shared<AsyncZipArg>();
1989     auto cbExec = [arg, zipEntity, flush](napi_env env) -> NapiBusinessError {
1990         if (!arg || !zipEntity || !zipEntity->zs) {
1991             return NapiBusinessError(EFAULT, true);
1992         }
1993         arg->errCode = inflateReset2(zipEntity->zs.get(), flush);
1994         if (arg->errCode < 0) {
1995             return NapiBusinessError(arg->errCode, true);
1996         }
1997         return NapiBusinessError(ERRNO_NOERR);
1998     };
1999 
2000     auto cbCompl = [arg](napi_env env, NapiBusinessError err) -> NapiValue {
2001         if (err) {
2002             return {env, err.GetNapiErr(env)};
2003         }
2004         if (!arg) {
2005             return {NapiValue::CreateUndefined(env)};
2006         }
2007         return {NapiValue::CreateInt32(env, arg->errCode)};
2008     };
2009 
2010     NapiValue thisVar(env, funcArg.GetThisVar());
2011     if (funcArg.GetArgc() == ArgumentCount::TWO) {
2012         return NapiAsyncWorkPromise(env, thisVar).Schedule(PROCEDURE_ZIP_NAME, cbExec, cbCompl).val_;
2013     }
2014 
2015     return NapiValue::CreateUndefined(env).val_;
2016 }
2017 
InflateReset(napi_env env,napi_callback_info info)2018 napi_value ZipNExporter::InflateReset(napi_env env, napi_callback_info info)
2019 {
2020     NapiFuncArg funcArg(env, info);
2021     if (!funcArg.InitArgs(ArgumentCount::ONE, ArgumentCount::TWO)) {
2022         NapiBusinessError().ThrowErr(env, EINVAL);
2023         return nullptr;
2024     }
2025 
2026     /* To get entity */
2027     auto zipEntity = NapiClass::GetEntityOf<ZipEntity>(env, funcArg.GetThisVar());
2028     if (!zipEntity) {
2029         NapiBusinessError().ThrowErr(env, EFAULT);
2030         return nullptr;
2031     }
2032 
2033     bool succ = CommonFunc::SetZStreamValue(env, funcArg);
2034     if (!succ) {
2035         return nullptr;
2036     }
2037 
2038     auto arg = make_shared<AsyncZipArg>();
2039     auto cbExec = [arg, zipEntity](napi_env env) -> NapiBusinessError {
2040         if (!arg || !zipEntity || !zipEntity->zs) {
2041             return NapiBusinessError(EFAULT, true);
2042         }
2043         arg->errCode = inflateReset(zipEntity->zs.get());
2044         if (arg->errCode < 0) {
2045             return NapiBusinessError(arg->errCode, true);
2046         }
2047         return NapiBusinessError(ERRNO_NOERR);
2048     };
2049 
2050     auto cbCompl = [arg](napi_env env, NapiBusinessError err) -> NapiValue {
2051         if (err) {
2052             return {env, err.GetNapiErr(env)};
2053         }
2054         if (!arg) {
2055             return {NapiValue::CreateUndefined(env)};
2056         }
2057         return {NapiValue::CreateInt32(env, arg->errCode)};
2058     };
2059 
2060     NapiValue thisVar(env, funcArg.GetThisVar());
2061     if (funcArg.GetArgc() == ArgumentCount::ONE) {
2062         return NapiAsyncWorkPromise(env, thisVar).Schedule(PROCEDURE_ZIP_NAME, cbExec, cbCompl).val_;
2063     }
2064 
2065     return NapiValue::CreateUndefined(env).val_;
2066 }
2067 
InflateBackInit(napi_env env,napi_callback_info info)2068 napi_value ZipNExporter::InflateBackInit(napi_env env, napi_callback_info info)
2069 {
2070     NapiFuncArg funcArg(env, info);
2071     if (!funcArg.InitArgs(ArgumentCount::THREE, ArgumentCount::FOUR)) {
2072         NapiBusinessError().ThrowErr(env, EINVAL);
2073         return nullptr;
2074     }
2075 
2076     /* To get entity */
2077     auto zipEntity = NapiClass::GetEntityOf<ZipEntity>(env, funcArg.GetThisVar());
2078     if (!zipEntity) {
2079         NapiBusinessError().ThrowErr(env, EFAULT);
2080         return nullptr;
2081     }
2082 
2083     bool succ = false;
2084     int32_t windowBits = 0;
2085     void *windowBuf = nullptr;
2086     size_t bufLen = 0;
2087     tie(succ, windowBits, windowBuf, bufLen) = CommonFunc::GetInflateBackInitArg(env, funcArg);
2088     if (!succ) {
2089         return nullptr;
2090     }
2091 
2092     auto arg = make_shared<AsyncZipArg>();
2093     auto cbExec = [arg, zipEntity, windowBits, windowBuf](napi_env env) -> NapiBusinessError {
2094         if (!arg || !zipEntity || !zipEntity->zs) {
2095             return NapiBusinessError(EFAULT, true);
2096         }
2097         arg->errCode = inflateBackInit(zipEntity->zs.get(), windowBits, static_cast<Bytef *>(windowBuf));
2098         if (arg->errCode < 0) {
2099             return NapiBusinessError(arg->errCode, true);
2100         }
2101         return NapiBusinessError(ERRNO_NOERR);
2102     };
2103 
2104     auto cbCompl = [arg](napi_env env, NapiBusinessError err) -> NapiValue {
2105         if (err) {
2106             return {env, err.GetNapiErr(env)};
2107         }
2108         if (!arg) {
2109             return {NapiValue::CreateUndefined(env)};
2110         }
2111         return {NapiValue::CreateInt32(env, arg->errCode)};
2112     };
2113 
2114     NapiValue thisVar(env, funcArg.GetThisVar());
2115     if (funcArg.GetArgc() == ArgumentCount::THREE) {
2116         return NapiAsyncWorkPromise(env, thisVar).Schedule(PROCEDURE_ZIP_NAME, cbExec, cbCompl).val_;
2117     }
2118 
2119     return NapiValue::CreateUndefined(env).val_;
2120 }
2121 
InFunc(void * inDesc,unsigned char ** buf)2122 static unsigned InFunc(void *inDesc, unsigned char **buf)
2123 {
2124     InOutDesc *in = static_cast<InOutDesc *>(inDesc);
2125     if (!in) {
2126         APP_LOGE("The in function callback is nullptr");
2127         return 0;
2128     }
2129 
2130     NapiReference cb(NapiValue(in->env, in->func));
2131     if (!cb || !cb.Deref(in->env).TypeIs(napi_function)) {
2132         NapiBusinessError().ThrowErr(in->env, EINVAL);
2133         return 0;
2134     }
2135     napi_value callback = cb.Deref(in->env).val_;
2136     napi_value argv[ArgumentCount::ONE] = {in->desc};
2137     napi_value globalObj = nullptr;
2138     napi_status status = napi_get_global(in->env, &globalObj);
2139     if (status != napi_ok) {
2140         NapiBusinessError().ThrowErr(in->env, EINVAL);
2141         return 0;
2142     }
2143     napi_value return_val = nullptr;
2144     status = napi_call_function(in->env, globalObj, callback, ArgumentCount::ONE, argv, &return_val);
2145     if (status != napi_ok) {
2146         NapiBusinessError().ThrowErr(in->env, EINVAL);
2147         return 0;
2148     }
2149 
2150     NapiValue bufNVal(in->env, return_val);
2151     void *buffer = nullptr;
2152     size_t bufLen = 0;
2153     bool succ = false;
2154     tie(succ, buffer, bufLen) = bufNVal.ToArrayBuffer();
2155     if (!succ) {
2156         NapiBusinessError().ThrowErr(in->env, EINVAL);
2157         return 0;
2158     }
2159     *buf = static_cast<unsigned char *>(buffer);
2160 
2161     return bufLen;
2162 }
2163 
OutFunc(void * outDesc,unsigned char * buf,unsigned len)2164 static int32_t OutFunc(void *outDesc, unsigned char *buf, unsigned len)
2165 {
2166     InOutDesc *out = static_cast<InOutDesc *>(outDesc);
2167     if (!out) {
2168         APP_LOGE("The out function callback is nullptr");
2169         return -1;
2170     }
2171 
2172     NapiReference cb(NapiValue(out->env, out->func));
2173     if (!cb || !cb.Deref(out->env).TypeIs(napi_function)) {
2174         NapiBusinessError().ThrowErr(out->env, EINVAL);
2175         return -1;
2176     }
2177     napi_value callback = cb.Deref(out->env).val_;
2178     void *data = nullptr;
2179     napi_value buffer = nullptr;
2180     napi_status status = napi_create_arraybuffer(out->env, len, &data, &buffer);
2181     if (status != napi_ok) {
2182         NapiBusinessError().ThrowErr(out->env, EINVAL);
2183         return -1;
2184     }
2185     if (memcpy_s(data, len, buf, len) != EOK) {
2186         NapiBusinessError().ThrowErr(out->env, EINVAL);
2187         return -1;
2188     }
2189     napi_value bufferLen = nullptr;
2190     status = napi_create_int32(out->env, len, &bufferLen);
2191     if (status != napi_ok) {
2192         NapiBusinessError().ThrowErr(out->env, EINVAL);
2193         return -1;
2194     }
2195     napi_value argv[ArgumentCount::THREE] = {out->desc, buffer, bufferLen};
2196     napi_value globalObj = nullptr;
2197     status = napi_get_global(out->env, &globalObj);
2198     if (status != napi_ok) {
2199         NapiBusinessError().ThrowErr(out->env, EINVAL);
2200         return -1;
2201     }
2202     napi_value return_val = nullptr;
2203     status = napi_call_function(out->env, globalObj, callback, ArgumentCount::THREE, argv, &return_val);
2204     if (status != napi_ok) {
2205         NapiBusinessError().ThrowErr(out->env, EINVAL);
2206         return -1;
2207     }
2208     int32_t result = 0;
2209     status = napi_get_value_int32(out->env, return_val, &result);
2210     if (status != napi_ok) {
2211         NapiBusinessError().ThrowErr(out->env, EINVAL);
2212         return -1;
2213     }
2214     return result;
2215 }
2216 
InflateBack(napi_env env,napi_callback_info info)2217 napi_value ZipNExporter::InflateBack(napi_env env, napi_callback_info info)
2218 {
2219     NapiFuncArg funcArg(env, info);
2220     if (!funcArg.InitArgs(ArgumentCount::FIVE, ArgumentCount::SIX)) {
2221         NapiBusinessError().ThrowErr(env, EINVAL);
2222         return nullptr;
2223     }
2224 
2225     auto arg = make_shared<AsyncZipArg>();
2226     /* To get entity */
2227     auto zipEntity = NapiClass::GetEntityOf<ZipEntity>(env, funcArg.GetThisVar());
2228     if (!arg || !zipEntity) {
2229         NapiBusinessError().ThrowErr(env, EFAULT);
2230         return nullptr;
2231     }
2232 
2233     bool succ = CommonFunc::SetZStreamValue(env, funcArg);
2234     if (!succ) {
2235         return nullptr;
2236     }
2237 
2238     auto inDesc = make_shared<InOutDesc>(env, funcArg[ArgumentPosition::SECOND], funcArg[ArgumentPosition::THIRD]);
2239     auto outDesc = make_shared<InOutDesc>(env, funcArg[ArgumentPosition::FOURTH], funcArg[ArgumentPosition::FIFTH]);
2240     arg->errCode = inflateBack(zipEntity->zs.get(), InFunc, inDesc.get(), OutFunc, outDesc.get());
2241     auto cbExec = [arg](napi_env env) -> NapiBusinessError {
2242         if (!arg) {
2243             return NapiBusinessError(EFAULT, true);
2244         }
2245         if (arg->errCode < 0) {
2246             return NapiBusinessError(arg->errCode, true);
2247         }
2248         return NapiBusinessError(ERRNO_NOERR);
2249     };
2250 
2251     auto cbCompl = [arg](napi_env env, NapiBusinessError err) -> NapiValue {
2252         if (err) {
2253             return {env, err.GetNapiErr(env)};
2254         }
2255         if (!arg) {
2256             return {NapiValue::CreateUndefined(env)};
2257         }
2258         return {NapiValue::CreateInt32(env, arg->errCode)};
2259     };
2260 
2261     NapiValue thisVar(env, funcArg.GetThisVar());
2262     if (funcArg.GetArgc() == ArgumentCount::FIVE) {
2263         return NapiAsyncWorkPromise(env, thisVar).Schedule(PROCEDURE_ZIP_NAME, cbExec, cbCompl).val_;
2264     }
2265 
2266     return NapiValue::CreateUndefined(env).val_;
2267 }
2268 
InflateBackEnd(napi_env env,napi_callback_info info)2269 napi_value ZipNExporter::InflateBackEnd(napi_env env, napi_callback_info info)
2270 {
2271     NapiFuncArg funcArg(env, info);
2272     if (!funcArg.InitArgs(ArgumentCount::ONE, ArgumentCount::TWO)) {
2273         NapiBusinessError().ThrowErr(env, EINVAL);
2274         return nullptr;
2275     }
2276 
2277     /* To get entity */
2278     auto zipEntity = NapiClass::GetEntityOf<ZipEntity>(env, funcArg.GetThisVar());
2279     if (!zipEntity) {
2280         NapiBusinessError().ThrowErr(env, EFAULT);
2281         return nullptr;
2282     }
2283 
2284     bool succ = CommonFunc::SetZStreamValue(env, funcArg);
2285     if (!succ) {
2286         return nullptr;
2287     }
2288 
2289     auto arg = make_shared<AsyncZipArg>();
2290     auto cbExec = [arg, zipEntity](napi_env env) -> NapiBusinessError {
2291         if (!arg || !zipEntity || !zipEntity->zs) {
2292             return NapiBusinessError(EFAULT, true);
2293         }
2294         arg->errCode = inflateBackEnd(zipEntity->zs.get());
2295         if (arg->errCode < 0) {
2296             return NapiBusinessError(arg->errCode, true);
2297         }
2298         return NapiBusinessError(ERRNO_NOERR);
2299     };
2300 
2301     auto cbCompl = [arg](napi_env env, NapiBusinessError err) -> NapiValue {
2302         if (err) {
2303             return {env, err.GetNapiErr(env)};
2304         }
2305         if (!arg) {
2306             return {NapiValue::CreateUndefined(env)};
2307         }
2308         return {NapiValue::CreateInt32(env, arg->errCode)};
2309     };
2310 
2311     NapiValue thisVar(env, funcArg.GetThisVar());
2312     if (funcArg.GetArgc() == ArgumentCount::ONE) {
2313         return NapiAsyncWorkPromise(env, thisVar).Schedule(PROCEDURE_ZIP_NAME, cbExec, cbCompl).val_;
2314     }
2315 
2316     return NapiValue::CreateUndefined(env).val_;
2317 }
2318 
InflateCodesUsed(napi_env env,napi_callback_info info)2319 napi_value ZipNExporter::InflateCodesUsed(napi_env env, napi_callback_info info)
2320 {
2321     NapiFuncArg funcArg(env, info);
2322     if (!funcArg.InitArgs(ArgumentCount::ONE, ArgumentCount::TWO)) {
2323         NapiBusinessError().ThrowErr(env, EINVAL);
2324         return nullptr;
2325     }
2326 
2327     /* To get entity */
2328     auto zipEntity = NapiClass::GetEntityOf<ZipEntity>(env, funcArg.GetThisVar());
2329     if (!zipEntity) {
2330         NapiBusinessError().ThrowErr(env, EFAULT);
2331         return nullptr;
2332     }
2333 
2334     bool succ = CommonFunc::SetZStreamValue(env, funcArg);
2335     if (!succ) {
2336         return nullptr;
2337     }
2338 
2339     auto arg = make_shared<AsyncZipArg>();
2340     auto cbExec = [arg, zipEntity](napi_env env) -> NapiBusinessError {
2341         if (!arg || !zipEntity || !zipEntity->zs) {
2342             return NapiBusinessError(EFAULT, true);
2343         }
2344         arg->errCode = static_cast<int32_t>(inflateCodesUsed(zipEntity->zs.get()));
2345         return NapiBusinessError(ERRNO_NOERR);
2346     };
2347 
2348     auto cbCompl = [arg](napi_env env, NapiBusinessError err) -> NapiValue {
2349         if (err) {
2350             return {env, err.GetNapiErr(env)};
2351         }
2352         if (!arg) {
2353             return {NapiValue::CreateUndefined(env)};
2354         }
2355         return {NapiValue::CreateUint32(env, arg->errCode)};
2356     };
2357 
2358     NapiValue thisVar(env, funcArg.GetThisVar());
2359     if (funcArg.GetArgc() == ArgumentCount::ONE) {
2360         return NapiAsyncWorkPromise(env, thisVar).Schedule(PROCEDURE_ZIP_NAME, cbExec, cbCompl).val_;
2361     }
2362 
2363     return NapiValue::CreateUndefined(env).val_;
2364 }
2365 
InflatePrime(napi_env env,napi_callback_info info)2366 napi_value ZipNExporter::InflatePrime(napi_env env, napi_callback_info info)
2367 {
2368     NapiFuncArg funcArg(env, info);
2369     if (!funcArg.InitArgs(ArgumentCount::THREE, ArgumentCount::FOUR)) {
2370         NapiBusinessError().ThrowErr(env, EINVAL);
2371         return nullptr;
2372     }
2373 
2374     /* To get entity */
2375     auto zipEntity = NapiClass::GetEntityOf<ZipEntity>(env, funcArg.GetThisVar());
2376     if (!zipEntity) {
2377         NapiBusinessError().ThrowErr(env, EFAULT);
2378         return nullptr;
2379     }
2380 
2381     bool succ = false;
2382     int32_t bits = 0;
2383     int32_t value = 0;
2384     tie(succ, bits, value) = CommonFunc::GetInflatePrimeArg(env, funcArg);
2385     if (!succ) {
2386         return nullptr;
2387     }
2388 
2389     auto arg = make_shared<AsyncZipArg>();
2390     auto cbExec = [arg, zipEntity, bits, value](napi_env env) -> NapiBusinessError {
2391         if (!arg || !zipEntity || !zipEntity->zs) {
2392             return NapiBusinessError(EFAULT, true);
2393         }
2394         arg->errCode = inflatePrime(zipEntity->zs.get(), bits, value);
2395         if (arg->errCode < 0) {
2396             return NapiBusinessError(arg->errCode, true);
2397         }
2398         return NapiBusinessError(ERRNO_NOERR);
2399     };
2400 
2401     auto cbCompl = [arg](napi_env env, NapiBusinessError err) -> NapiValue {
2402         if (err) {
2403             return {env, err.GetNapiErr(env)};
2404         }
2405         if (!arg) {
2406             return {NapiValue::CreateUndefined(env)};
2407         }
2408         return {NapiValue::CreateInt32(env, arg->errCode)};
2409     };
2410 
2411     NapiValue thisVar(env, funcArg.GetThisVar());
2412     if (funcArg.GetArgc() == ArgumentCount::THREE) {
2413         return NapiAsyncWorkPromise(env, thisVar).Schedule(PROCEDURE_ZIP_NAME, cbExec, cbCompl).val_;
2414     }
2415 
2416     return NapiValue::CreateUndefined(env).val_;
2417 }
2418 
InflateMark(napi_env env,napi_callback_info info)2419 napi_value ZipNExporter::InflateMark(napi_env env, napi_callback_info info)
2420 {
2421     NapiFuncArg funcArg(env, info);
2422     if (!funcArg.InitArgs(ArgumentCount::ONE, ArgumentCount::TWO)) {
2423         NapiBusinessError().ThrowErr(env, EINVAL);
2424         return nullptr;
2425     }
2426 
2427     /* To get entity */
2428     auto zipEntity = NapiClass::GetEntityOf<ZipEntity>(env, funcArg.GetThisVar());
2429     if (!zipEntity) {
2430         NapiBusinessError().ThrowErr(env, EFAULT);
2431         return nullptr;
2432     }
2433 
2434     bool succ = CommonFunc::SetZStreamValue(env, funcArg);
2435     if (!succ) {
2436         return nullptr;
2437     }
2438 
2439     auto arg = make_shared<AsyncZipArg>();
2440     auto cbExec = [arg, zipEntity](napi_env env) -> NapiBusinessError {
2441         if (!arg || !zipEntity || !zipEntity->zs) {
2442             return NapiBusinessError(EFAULT, true);
2443         }
2444         arg->errCode = inflateMark(zipEntity->zs.get());
2445         return NapiBusinessError(ERRNO_NOERR);
2446     };
2447 
2448     auto cbCompl = [arg](napi_env env, NapiBusinessError err) -> NapiValue {
2449         if (err) {
2450             return {env, err.GetNapiErr(env)};
2451         }
2452         if (!arg) {
2453             return {NapiValue::CreateUndefined(env)};
2454         }
2455         return {NapiValue::CreateInt32(env, arg->errCode)};
2456     };
2457 
2458     NapiValue thisVar(env, funcArg.GetThisVar());
2459     if (funcArg.GetArgc() == ArgumentCount::ONE) {
2460         return NapiAsyncWorkPromise(env, thisVar).Schedule(PROCEDURE_ZIP_NAME, cbExec, cbCompl).val_;
2461     }
2462 
2463     return NapiValue::CreateUndefined(env).val_;
2464 }
2465 
InflateValidate(napi_env env,napi_callback_info info)2466 napi_value ZipNExporter::InflateValidate(napi_env env, napi_callback_info info)
2467 {
2468     NapiFuncArg funcArg(env, info);
2469     if (!funcArg.InitArgs(ArgumentCount::TWO, ArgumentCount::THREE)) {
2470         NapiBusinessError().ThrowErr(env, EINVAL);
2471         return nullptr;
2472     }
2473 
2474     /* To get entity */
2475     auto zipEntity = NapiClass::GetEntityOf<ZipEntity>(env, funcArg.GetThisVar());
2476     if (!zipEntity) {
2477         NapiBusinessError().ThrowErr(env, EFAULT);
2478         return nullptr;
2479     }
2480 
2481     bool succ = false;
2482     int32_t check = 0;
2483     tie(succ, check) = CommonFunc::GetInflateValidateArg(env, funcArg);
2484     if (!succ) {
2485         return nullptr;
2486     }
2487 
2488     auto arg = make_shared<AsyncZipArg>();
2489     auto cbExec = [arg, zipEntity, check](napi_env env) -> NapiBusinessError {
2490         if (!arg || !zipEntity || !zipEntity->zs) {
2491             return NapiBusinessError(EFAULT, true);
2492         }
2493         arg->errCode = inflateValidate(zipEntity->zs.get(), check);
2494         if (arg->errCode < 0) {
2495             return NapiBusinessError(arg->errCode, true);
2496         }
2497         return NapiBusinessError(ERRNO_NOERR);
2498     };
2499 
2500     auto cbCompl = [arg](napi_env env, NapiBusinessError err) -> NapiValue {
2501         if (err) {
2502             return {env, err.GetNapiErr(env)};
2503         }
2504         if (!arg) {
2505             return {NapiValue::CreateUndefined(env)};
2506         }
2507         return {NapiValue::CreateInt32(env, arg->errCode)};
2508     };
2509 
2510     NapiValue thisVar(env, funcArg.GetThisVar());
2511     if (funcArg.GetArgc() == ArgumentCount::TWO) {
2512         return NapiAsyncWorkPromise(env, thisVar).Schedule(PROCEDURE_ZIP_NAME, cbExec, cbCompl).val_;
2513     }
2514 
2515     return NapiValue::CreateUndefined(env).val_;
2516 }
2517 
InflateSyncPoint(napi_env env,napi_callback_info info)2518 napi_value ZipNExporter::InflateSyncPoint(napi_env env, napi_callback_info info)
2519 {
2520     NapiFuncArg funcArg(env, info);
2521     if (!funcArg.InitArgs(ArgumentCount::ONE, ArgumentCount::TWO)) {
2522         NapiBusinessError().ThrowErr(env, EINVAL);
2523         return nullptr;
2524     }
2525 
2526     /* To get entity */
2527     auto zipEntity = NapiClass::GetEntityOf<ZipEntity>(env, funcArg.GetThisVar());
2528     if (!zipEntity) {
2529         NapiBusinessError().ThrowErr(env, EFAULT);
2530         return nullptr;
2531     }
2532 
2533     bool succ = CommonFunc::SetZStreamValue(env, funcArg);
2534     if (!succ) {
2535         return nullptr;
2536     }
2537 
2538     auto arg = make_shared<AsyncZipArg>();
2539     auto cbExec = [arg, zipEntity](napi_env env) -> NapiBusinessError {
2540         if (!arg || !zipEntity || !zipEntity->zs) {
2541             return NapiBusinessError(EFAULT, true);
2542         }
2543         arg->errCode = inflateSyncPoint(zipEntity->zs.get());
2544         if (arg->errCode < 0) {
2545             return NapiBusinessError(arg->errCode, true);
2546         }
2547         return NapiBusinessError(ERRNO_NOERR);
2548     };
2549 
2550     auto cbCompl = [arg](napi_env env, NapiBusinessError err) -> NapiValue {
2551         if (err) {
2552             return {env, err.GetNapiErr(env)};
2553         }
2554         if (!arg) {
2555             return {NapiValue::CreateUndefined(env)};
2556         }
2557         return {NapiValue::CreateInt32(env, arg->errCode)};
2558     };
2559 
2560     NapiValue thisVar(env, funcArg.GetThisVar());
2561     if (funcArg.GetArgc() == ArgumentCount::ONE) {
2562         return NapiAsyncWorkPromise(env, thisVar).Schedule(PROCEDURE_ZIP_NAME, cbExec, cbCompl).val_;
2563     }
2564 
2565     return NapiValue::CreateUndefined(env).val_;
2566 }
2567 
InflateCopy(napi_env env,napi_callback_info info)2568 napi_value ZipNExporter::InflateCopy(napi_env env, napi_callback_info info)
2569 {
2570     NapiFuncArg funcArg(env, info);
2571     if (!funcArg.InitArgs(ArgumentCount::ONE, ArgumentCount::TWO)) {
2572         NapiBusinessError().ThrowErr(env, EINVAL);
2573         return nullptr;
2574     }
2575 
2576     /* To get entity */
2577     auto zipEntity = NapiClass::GetEntityOf<ZipEntity>(env, funcArg.GetThisVar());
2578     if (!zipEntity) {
2579         NapiBusinessError().ThrowErr(env, EFAULT);
2580         return nullptr;
2581     }
2582 
2583     auto srcZipEntity = NapiClass::GetEntityOf<ZipEntity>(env, funcArg[ArgumentPosition::FIRST]);
2584     if (!srcZipEntity) {
2585         NapiBusinessError().ThrowErr(env, EINVAL);
2586         return nullptr;
2587     }
2588 
2589     auto arg = make_shared<AsyncZipArg>();
2590     auto cbExec = [arg, zipEntity, srcZipEntity](napi_env env) -> NapiBusinessError {
2591         if (!arg || !zipEntity || !srcZipEntity) {
2592             return NapiBusinessError(EFAULT, true);
2593         }
2594 
2595         if (!zipEntity->zs) {
2596             std::unique_ptr<z_stream> zs = std::make_unique<z_stream>();
2597             zipEntity->zs.swap(zs);
2598         }
2599         arg->errCode = inflateCopy(zipEntity->zs.get(), srcZipEntity->zs.get());
2600         if (arg->errCode < 0) {
2601             return NapiBusinessError(arg->errCode, true);
2602         }
2603         return NapiBusinessError(ERRNO_NOERR);
2604     };
2605 
2606     auto cbCompl = [arg](napi_env env, NapiBusinessError err) -> NapiValue {
2607         if (err) {
2608             return {env, err.GetNapiErr(env)};
2609         }
2610         if (!arg) {
2611             return {NapiValue::CreateUndefined(env)};
2612         }
2613         return {NapiValue::CreateInt32(env, arg->errCode)};
2614     };
2615 
2616     NapiValue thisVar(env, funcArg.GetThisVar());
2617     if (funcArg.GetArgc() == ArgumentCount::ONE) {
2618         return NapiAsyncWorkPromise(env, thisVar).Schedule(PROCEDURE_ZIP_NAME, cbExec, cbCompl).val_;
2619     }
2620 
2621     return NapiValue::CreateUndefined(env).val_;
2622 }
2623 
InflateGetHeader(napi_env env,napi_callback_info info)2624 napi_value ZipNExporter::InflateGetHeader(napi_env env, napi_callback_info info)
2625 {
2626     NapiFuncArg funcArg(env, info);
2627     if (!funcArg.InitArgs(ArgumentCount::TWO, ArgumentCount::THREE)) {
2628         NapiBusinessError().ThrowErr(env, EINVAL);
2629         return nullptr;
2630     }
2631 
2632     /* To get entity */
2633     auto zipEntity = NapiClass::GetEntityOf<ZipEntity>(env, funcArg.GetThisVar());
2634     if (!zipEntity) {
2635         NapiBusinessError().ThrowErr(env, EFAULT);
2636         return nullptr;
2637     }
2638 
2639     bool succ = false;
2640     gz_header gzHeader = {};
2641     tie(succ, gzHeader) = CommonFunc::GetInflateGetHeaderArg(env, funcArg);
2642     if (!succ) {
2643         return nullptr;
2644     }
2645 
2646     auto arg = make_shared<AsyncZipArg>();
2647     auto cbExec = [arg, zipEntity, gzHeader](napi_env env) -> NapiBusinessError {
2648         if (!arg || !zipEntity || !zipEntity->zs) {
2649             return NapiBusinessError(EFAULT, true);
2650         }
2651         arg->errCode = inflateGetHeader(zipEntity->zs.get(), const_cast<gz_headerp>(&gzHeader));
2652         if (arg->errCode < 0) {
2653             return NapiBusinessError(arg->errCode, true);
2654         }
2655         return NapiBusinessError(ERRNO_NOERR);
2656     };
2657 
2658     auto cbCompl = [arg](napi_env env, NapiBusinessError err) -> NapiValue {
2659         if (err) {
2660             return {env, err.GetNapiErr(env)};
2661         }
2662         if (!arg) {
2663             return {NapiValue::CreateUndefined(env)};
2664         }
2665         return {NapiValue::CreateInt32(env, arg->errCode)};
2666     };
2667 
2668     NapiValue thisVar(env, funcArg.GetThisVar());
2669     if (funcArg.GetArgc() == ArgumentCount::TWO) {
2670         return NapiAsyncWorkPromise(env, thisVar).Schedule(PROCEDURE_ZIP_NAME, cbExec, cbCompl).val_;
2671     }
2672 
2673     return NapiValue::CreateUndefined(env).val_;
2674 }
2675 
2676 }  // namespace LIBZIP
2677 }  // namespace AppExecFwk
2678 }  // namespace OHOS
2679