• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2022 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 #include "napi_zlib.h"
16 
17 #include <cstring>
18 #include <uv.h>
19 #include <vector>
20 
21 #include "app_log_wrapper.h"
22 #include "file_path.h"
23 #include "bundle_errors.h"
24 #include "business_error.h"
25 #include "common_func.h"
26 #include "napi/native_common.h"
27 #include "napi/native_node_api.h"
28 #include "napi_arg.h"
29 #include "napi_constants.h"
30 #include "napi_zlib_common.h"
31 #include "zip.h"
32 #include "zip_utils.h"
33 #include "zlib_callback_info.h"
34 
35 using namespace OHOS::AppExecFwk;
36 
37 namespace OHOS {
38 namespace AppExecFwk {
39 namespace LIBZIP {
40 namespace {
41 constexpr size_t ARGS_MAX_COUNT = 10;
42 constexpr int32_t PARAM3 = 3;
43 constexpr int32_t PARAM2 = 2;
44 const char* WRONG_PARAM = "wrong param type";
45 }
46 
47 #define COMPRESS_LEVE_CHECK(level, ret)                                                            \
48     if (!(level == COMPRESS_LEVEL_NO_COMPRESSION || level == COMPRESS_LEVEL_DEFAULT_COMPRESSION || \
49             level == COMPRESS_LEVEL_BEST_SPEED || level == COMPRESS_LEVEL_BEST_COMPRESSION)) {     \
50         APP_LOGE("level parameter =[%{public}d] value is incorrect", (int)level);               \
51         return ret;                                                                                \
52     }
53 
54 #define COMPRESS_STRATEGY_CHECK(strategy, false)                                                      \
55     if (!(strategy == COMPRESS_STRATEGY_DEFAULT_STRATEGY || strategy == COMPRESS_STRATEGY_FILTERED || \
56             strategy == COMPRESS_STRATEGY_HUFFMAN_ONLY || strategy == COMPRESS_STRATEGY_RLE ||        \
57             strategy == COMPRESS_STRATEGY_FIXED)) {                                                   \
58         APP_LOGE("strategy parameter= [%{public}d] value is incorrect", (int)strategy);            \
59         return ret;                                                                                   \
60     }
61 
62 #define COMPRESS_MEM_CHECK(mem, false)                                                                            \
63     if (!(mem == MEM_LEVEL_MIN_MEMLEVEL || mem == MEM_LEVEL_DEFAULT_MEMLEVEL || mem == MEM_LEVEL_MAX_MEMLEVEL)) { \
64         APP_LOGE("memLevel parameter =[%{public}d] value is incorrect", (int)mem);                             \
65         return ret;                                                                                               \
66     }
67 
68 void CompressExcute(napi_env env, AsyncZipCallbackInfo *asyncZipCallbackInfo);
69 void DecompressExcute(napi_env env, AsyncZipCallbackInfo *asyncZipCallbackInfo);
70 napi_value UnwrapZipParam(CallZipUnzipParam &param, napi_env env, napi_value *args, size_t argc);
71 napi_value UnwrapUnZipParam(CallZipUnzipParam &param, napi_env env, napi_value *args, size_t argc);
72 napi_value ZipFileWrap(napi_env env, napi_callback_info info, AsyncZipCallbackInfo *asyncZipCallbackInfo);
73 napi_value UnwrapStringParam(std::string &str, napi_env env, napi_value argv);
74 bool UnwrapOptionsParams(OPTIONS &options, napi_env env, napi_value arg);
75 
76 /**
77  * @brief FlushType data initialization.
78  *
79  * @param env The environment that the Node-API call is invoked under.
80  * @param exports An empty object via the exports parameter as a convenience.
81  *
82  * @return The return value from Init is treated as the exports object for the module.
83  */
FlushTypeInit(napi_env env,napi_value exports)84 napi_value FlushTypeInit(napi_env env, napi_value exports)
85 {
86     APP_LOGD("%{public}s called.", __func__);
87     const int FLUSH_TYPE_NO_FLUSH = 0;
88     const int FLUSH_TYPE_PARTIAL_FLUSH = 1;
89     const int FLUSH_TYPE_SYNC_FLUSH = 2;
90     const int FLUSH_TYPE_FULL_FLUSH = 3;
91     const int FLUSH_TYPE_FINISH = 4;
92     const int FLUSH_TYPE_BLOCK = 5;
93     const int FLUSH_TYPE_TREES = 6;
94 
95     napi_value flushType = nullptr;
96     napi_create_object(env, &flushType);
97     SetNamedProperty(env, flushType, "FLUSH_TYPE_NO_FLUSH", FLUSH_TYPE_NO_FLUSH);
98     SetNamedProperty(env, flushType, "FLUSH_TYPE_PARTIAL_FLUSH", FLUSH_TYPE_PARTIAL_FLUSH);
99     SetNamedProperty(env, flushType, "FLUSH_TYPE_SYNC_FLUSH", FLUSH_TYPE_SYNC_FLUSH);
100     SetNamedProperty(env, flushType, "FLUSH_TYPE_FULL_FLUSH", FLUSH_TYPE_FULL_FLUSH);
101     SetNamedProperty(env, flushType, "FLUSH_TYPE_FINISH", FLUSH_TYPE_FINISH);
102     SetNamedProperty(env, flushType, "FLUSH_TYPE_BLOCK", FLUSH_TYPE_BLOCK);
103     SetNamedProperty(env, flushType, "FLUSH_TYPE_TREES", FLUSH_TYPE_TREES);
104 
105     napi_property_descriptor properties[] = {
106         DECLARE_NAPI_PROPERTY("FlushType", flushType),
107     };
108     NAPI_CALL(env, napi_define_properties(env, exports, sizeof(properties) / sizeof(properties[0]), properties));
109 
110     return exports;
111 }
112 /**
113  * @brief CompressLevel data initialization.
114  *
115  * @param env The environment that the Node-API call is invoked under.
116  * @param exports An empty object via the exports parameter as a convenience.
117  *
118  * @return The return value from Init is treated as the exports object for the module.
119  */
CompressLevelInit(napi_env env,napi_value exports)120 napi_value CompressLevelInit(napi_env env, napi_value exports)
121 {
122     APP_LOGD("%{public}s called.", __func__);
123     const int COMPRESS_LEVEL_NO_COMPRESSION = 0;
124     const int COMPRESS_LEVEL_BEST_SPEED = 1;
125     const int COMPRESS_LEVEL_BEST_COMPRESSION = 9;
126     const int COMPRESS_LEVEL_DEFAULT_COMPRESSION = -1;
127 
128     napi_value compressLevel = nullptr;
129     napi_create_object(env, &compressLevel);
130     SetNamedProperty(env, compressLevel, "COMPRESS_LEVEL_NO_COMPRESSION", COMPRESS_LEVEL_NO_COMPRESSION);
131     SetNamedProperty(env, compressLevel, "COMPRESS_LEVEL_BEST_SPEED", COMPRESS_LEVEL_BEST_SPEED);
132     SetNamedProperty(env, compressLevel, "COMPRESS_LEVEL_BEST_COMPRESSION", COMPRESS_LEVEL_BEST_COMPRESSION);
133     SetNamedProperty(env, compressLevel, "COMPRESS_LEVEL_DEFAULT_COMPRESSION", COMPRESS_LEVEL_DEFAULT_COMPRESSION);
134 
135     napi_property_descriptor properties[] = {
136         DECLARE_NAPI_PROPERTY("CompressLevel", compressLevel),
137     };
138     NAPI_CALL(env, napi_define_properties(env, exports, sizeof(properties) / sizeof(properties[0]), properties));
139 
140     return exports;
141 }
142 /**
143  * @brief CompressStrategy data initialization.
144  *
145  * @param env The environment that the Node-API call is invoked under.
146  * @param exports An empty object via the exports parameter as a convenience.
147  *
148  * @return The return value from Init is treated as the exports object for the module.
149  */
CompressStrategyInit(napi_env env,napi_value exports)150 napi_value CompressStrategyInit(napi_env env, napi_value exports)
151 {
152     APP_LOGD("%{public}s called.", __func__);
153     const int COMPRESS_STRATEGY_DEFAULT_STRATEGY = 0;
154     const int COMPRESS_STRATEGY_FILTERED = 1;
155     const int COMPRESS_STRATEGY_HUFFMAN_ONLY = 2;
156     const int COMPRESS_STRATEGY_RLE = 3;
157     const int COMPRESS_STRATEGY_FIXED = 4;
158 
159     napi_value compressStrategy = nullptr;
160     napi_create_object(env, &compressStrategy);
161     SetNamedProperty(env, compressStrategy, "COMPRESS_STRATEGY_DEFAULT_STRATEGY", COMPRESS_STRATEGY_DEFAULT_STRATEGY);
162     SetNamedProperty(env, compressStrategy, "COMPRESS_STRATEGY_FILTERED", COMPRESS_STRATEGY_FILTERED);
163     SetNamedProperty(env, compressStrategy, "COMPRESS_STRATEGY_HUFFMAN_ONLY", COMPRESS_STRATEGY_HUFFMAN_ONLY);
164     SetNamedProperty(env, compressStrategy, "COMPRESS_STRATEGY_RLE", COMPRESS_STRATEGY_RLE);
165     SetNamedProperty(env, compressStrategy, "COMPRESS_STRATEGY_FIXED", COMPRESS_STRATEGY_FIXED);
166 
167     napi_property_descriptor properties[] = {
168         DECLARE_NAPI_PROPERTY("CompressStrategy", compressStrategy),
169     };
170     NAPI_CALL(env, napi_define_properties(env, exports, sizeof(properties) / sizeof(properties[0]), properties));
171 
172     return exports;
173 }
174 /**
175  * @brief MemLevel data initialization.
176  *
177  * @param env The environment that the Node-API call is invoked under.
178  * @param exports An empty object via the exports parameter as a convenience.
179  *
180  * @return The return value from Init is treated as the exports object for the module.
181  */
MemLevelInit(napi_env env,napi_value exports)182 napi_value MemLevelInit(napi_env env, napi_value exports)
183 {
184     APP_LOGD("%{public}s called.", __func__);
185     const int MEM_LEVEL_MIN = 1;
186     const int MEM_LEVEL_DEFAULT = 8;
187     const int MEM_LEVEL_MAX = 9;
188 
189     napi_value memLevel = nullptr;
190     napi_create_object(env, &memLevel);
191     SetNamedProperty(env, memLevel, "MEM_LEVEL_MIN", MEM_LEVEL_MIN);
192     SetNamedProperty(env, memLevel, "MEM_LEVEL_DEFAULT", MEM_LEVEL_DEFAULT);
193     SetNamedProperty(env, memLevel, "MEM_LEVEL_MAX", MEM_LEVEL_MAX);
194 
195     napi_property_descriptor properties[] = {
196         DECLARE_NAPI_PROPERTY("MemLevel", memLevel),
197     };
198     NAPI_CALL(env, napi_define_properties(env, exports, sizeof(properties) / sizeof(properties[0]), properties));
199 
200     return exports;
201 }
202 /**
203  * @brief Errorcode data initialization.
204  *
205  * @param env The environment that the Node-API call is invoked under.
206  * @param exports An empty object via the exports parameter as a convenience.
207  *
208  * @return The return value from Init is treated as the exports object for the module.
209  */
ErrorCodeInit(napi_env env,napi_value exports)210 napi_value ErrorCodeInit(napi_env env, napi_value exports)
211 {
212     APP_LOGD("%{public}s called.", __func__);
213 
214     const int ERROR_CODE_OK = 0;
215     const int ERROR_CODE_STREAM_END = 1;
216     const int ERROR_CODE_NEED_DICT = 2;
217     const int ERROR_CODE_ERRNO = -1;
218     const int ERROR_CODE_STREAM_ERROR = -2;
219     const int ERROR_CODE_DATA_ERROR = -3;
220     const int ERROR_CODE_MEM_ERROR = -4;
221     const int ERROR_CODE_BUF_ERROR = -5;
222     const int ERROR_CODE_VERSION_ERROR = -6;
223 
224     napi_value errorCode = nullptr;
225     napi_create_object(env, &errorCode);
226     SetNamedProperty(env, errorCode, "ERROR_CODE_OK", ERROR_CODE_OK);
227     SetNamedProperty(env, errorCode, "ERROR_CODE_STREAM_END", ERROR_CODE_STREAM_END);
228     SetNamedProperty(env, errorCode, "ERROR_CODE_NEED_DICT", ERROR_CODE_NEED_DICT);
229     SetNamedProperty(env, errorCode, "ERROR_CODE_ERRNO", ERROR_CODE_ERRNO);
230     SetNamedProperty(env, errorCode, "ERROR_CODE_STREAM_ERROR", ERROR_CODE_STREAM_ERROR);
231     SetNamedProperty(env, errorCode, "ERROR_CODE_DATA_ERROR", ERROR_CODE_DATA_ERROR);
232     SetNamedProperty(env, errorCode, "ERROR_CODE_MEM_ERROR", ERROR_CODE_MEM_ERROR);
233     SetNamedProperty(env, errorCode, "ERROR_CODE_BUF_ERROR", ERROR_CODE_BUF_ERROR);
234     SetNamedProperty(env, errorCode, "ERROR_CODE_VERSION_ERROR", ERROR_CODE_VERSION_ERROR);
235 
236     napi_property_descriptor properties[] = {
237         DECLARE_NAPI_PROPERTY("ErrorCode", errorCode),
238     };
239     NAPI_CALL(env, napi_define_properties(env, exports, sizeof(properties) / sizeof(properties[0]), properties));
240 
241     return exports;
242 }
243 
244 /**
245  * @brief FeatureAbility NAPI module registration.
246  *
247  * @param env The environment that the Node-API call is invoked under.
248  * @param exports An empty object via the exports parameter as a convenience.
249  *
250  * @return The return value from Init is treated as the exports object for the module.
251  */
ZlibInit(napi_env env,napi_value exports)252 napi_value ZlibInit(napi_env env, napi_value exports)
253 {
254     APP_LOGD("%{public}s,called", __func__);
255 
256     napi_property_descriptor properties[] = {
257         DECLARE_NAPI_FUNCTION("zipFile", NAPI_ZipFile),
258         DECLARE_NAPI_FUNCTION("unzipFile", NAPI_UnzipFile),
259         DECLARE_NAPI_FUNCTION("compressFile", CompressFile),
260         DECLARE_NAPI_FUNCTION("decompressFile", DecompressFile),
261     };
262 
263     NAPI_CALL(env, napi_define_properties(env, exports, sizeof(properties) / sizeof(properties[0]), properties));
264 
265     return exports;
266 }
267 
CreateZipAsyncCallbackInfo(napi_env env)268 AsyncZipCallbackInfo *CreateZipAsyncCallbackInfo(napi_env env)
269 {
270     APP_LOGD("%{public}s called.", __func__);
271     napi_status ret;
272     napi_value global = 0;
273     const napi_extended_error_info *errorInfo = nullptr;
274     ret = napi_get_global(env, &global);
275     if (ret != napi_ok) {
276         napi_get_last_error_info(env, &errorInfo);
277         if (errorInfo == nullptr) {
278             APP_LOGE("%{public}s errorInfo is null", __func__);
279             return nullptr;
280         }
281         APP_LOGE("%{public}s get_global=%{public}d err:%{public}s", __func__, ret, errorInfo->error_message);
282     }
283 
284     AsyncZipCallbackInfo *asyncCallbackInfo = new (std::nothrow) AsyncZipCallbackInfo {
285         .asyncWork = nullptr,
286         .zlibCallbackInfo = nullptr,
287     };
288     if (asyncCallbackInfo == nullptr) {
289         APP_LOGE("%{public}s asyncCallbackInfo is null", __func__);
290         return nullptr;
291     }
292     APP_LOGD("%{public}s end.", __func__);
293     return asyncCallbackInfo;
294 }
295 
UnwrapStringParam(std::string & str,napi_env env,napi_value argv)296 napi_value UnwrapStringParam(std::string &str, napi_env env, napi_value argv)
297 {
298     APP_LOGD("%{public}s,called", __func__);
299     // unwrap the param[0]
300     napi_valuetype valueType = napi_valuetype::napi_undefined;
301     napi_status rev = napi_typeof(env, argv, &valueType);
302     if (rev != napi_ok) {
303         return nullptr;
304     }
305 
306     if (valueType != napi_valuetype::napi_string) {
307         APP_LOGI("%{public}s called, Parameter type does not match", __func__);
308         return nullptr;
309     }
310 
311     size_t len;
312     napi_status status = napi_get_value_string_utf8(env, argv, nullptr, 0, &len);
313     if (status != napi_ok) {
314         APP_LOGI("%{public}s called, Get locale tag length failed", __func__);
315         return nullptr;
316     }
317     std::vector<char> buf(len + 1);
318     status = napi_get_value_string_utf8(env, argv, buf.data(), len + 1, &len);
319     if (status != napi_ok) {
320         APP_LOGI("%{public}s called, Get locale tag failed", __func__);
321         return nullptr;
322     }
323     str = std::string(buf.data());
324 
325     napi_value result;
326     NAPI_CALL(env, napi_create_int32(env, 1, &result));
327     return result;
328 }
329 
UnwrapOptionsParams(OPTIONS & options,napi_env env,napi_value arg)330 bool UnwrapOptionsParams(OPTIONS &options, napi_env env, napi_value arg)
331 {
332     if (!IsTypeForNapiValue(env, arg, napi_object)) {
333         return false;
334     }
335     napi_valuetype jsValueType = napi_undefined;
336     napi_value jsProNameList = nullptr;
337     uint32_t jsProCount = 0;
338 
339     NAPI_CALL_BASE(env, napi_get_property_names(env, arg, &jsProNameList), false);
340     NAPI_CALL_BASE(env, napi_get_array_length(env, jsProNameList, &jsProCount), false);
341 
342     napi_value jsProName = nullptr;
343     napi_value jsProValue = nullptr;
344 
345     for (uint32_t index = 0; index < jsProCount; index++) {
346         NAPI_CALL_BASE(env, napi_get_element(env, jsProNameList, index, &jsProName), false);
347         std::string strProName = UnwrapStringFromJS(env, jsProName, std::string());
348         APP_LOGD("%{public}s called. Property name=%{public}s.", __func__, strProName.c_str());
349         NAPI_CALL_BASE(env, napi_get_named_property(env, arg, strProName.c_str(), &jsProValue), false);
350         NAPI_CALL_BASE(env, napi_typeof(env, jsProValue, &jsValueType), false);
351 
352         int ret = 0;
353         if (strProName == std::string("flush")) {
354             if (UnwrapIntValue(env, jsProValue, ret)) {
355                 options.flush = static_cast<FLUSH_TYPE>(ret);
356             }
357         } else if (strProName == std::string("finishFlush")) {
358             if (UnwrapIntValue(env, jsProValue, ret)) {
359                 options.finishFlush = static_cast<FLUSH_TYPE>(ret);
360             }
361         } else if (strProName == std::string("chunkSize")) {
362             if (UnwrapIntValue(env, jsProValue, ret)) {
363                 options.chunkSize = ret;
364             }
365         } else if (strProName == std::string("level")) {
366             if (UnwrapIntValue(env, jsProValue, ret)) {
367                 COMPRESS_LEVE_CHECK(ret, false)
368                 options.level = static_cast<COMPRESS_LEVEL>(ret);
369             }
370         } else if (strProName == std::string("memLevel")) {
371             if (UnwrapIntValue(env, jsProValue, ret)) {
372                 COMPRESS_MEM_CHECK(ret, false)
373                 options.memLevel = static_cast<MEMORY_LEVEL>(ret);
374             }
375         } else if (strProName == std::string("strategy")) {
376             if (UnwrapIntValue(env, jsProValue, ret)) {
377                 COMPRESS_STRATEGY_CHECK(ret, false)
378                 options.strategy = static_cast<COMPRESS_STRATEGY>(ret);
379             }
380         }
381     }
382     return true;
383 }
384 
UnwrapZipParam(CallZipUnzipParam & param,napi_env env,napi_value * args,size_t argc)385 napi_value UnwrapZipParam(CallZipUnzipParam &param, napi_env env, napi_value *args, size_t argc)
386 {
387     APP_LOGD("%{public}s,called", __func__);
388     size_t argcPromise = 3;
389     if (argc < argcPromise) {
390         APP_LOGI("%{public}s called, param count is wrong", __func__);
391         return nullptr;
392     }
393 
394     // unwrap the param[0]
395     if (UnwrapStringParam(param.src, env, args[0]) == nullptr) {
396         APP_LOGI("%{public}s called, args[0] error", __func__);
397         return nullptr;
398     }
399 
400     // unwrap the param[1]
401     if (UnwrapStringParam(param.dest, env, args[1]) == nullptr) {
402         APP_LOGI("%{public}s called, args[1] error", __func__);
403         return nullptr;
404     }
405 
406     // unwrap the param[2]
407     if (!UnwrapOptionsParams(param.options, env, args[2])) {
408         APP_LOGI("%{public}s called, args[2] error", __func__);
409         return nullptr;
410     }
411     // create reutrn
412     napi_value ret = 0;
413     NAPI_CALL_BASE(env, napi_create_int32(env, 0, &ret), nullptr);
414     return ret;
415 }
416 
UnwrapUnZipParam(CallZipUnzipParam & param,napi_env env,napi_value * args,size_t argc)417 napi_value UnwrapUnZipParam(CallZipUnzipParam &param, napi_env env, napi_value *args, size_t argc)
418 {
419     APP_LOGD("%{public}s,called", __func__);
420     size_t argcPromise = 3;
421     if (argc < argcPromise) {
422         return nullptr;
423     }
424     // unwrap the param[0]
425     if (UnwrapStringParam(param.src, env, args[0]) == nullptr) {
426         return nullptr;
427     }
428 
429     // unwrap the param[1]
430     if (UnwrapStringParam(param.dest, env, args[1]) == nullptr) {
431         return nullptr;
432     }
433 
434     // create reutrn
435     napi_value ret = 0;
436     NAPI_CALL_BASE(env, napi_create_int32(env, 0, &ret), nullptr);
437     return ret;
438 }
439 
440 /**
441  * @brief Zlib NAPI method : zipFile.
442  *
443  * @param env The environment that the Node-API call is invoked under.
444  * @param info The callback info passed into the callback function.
445  *
446  * @return The return value from NAPI C++ to JS for the module.
447  */
NAPI_ZipFile(napi_env env,napi_callback_info info)448 napi_value NAPI_ZipFile(napi_env env, napi_callback_info info)
449 {
450     APP_LOGD("%{public}s,called", __func__);
451     napi_value args[ARGS_MAX_COUNT] = {nullptr};
452     napi_value ret = 0;
453     size_t argcAsync = 4;
454     const size_t argcPromise = 3;
455     NAPI_CALL(env, napi_get_cb_info(env, info, &argcAsync, args, nullptr, nullptr));
456     if (argcAsync < argcPromise || argcAsync > ARGS_MAX_COUNT) {
457         APP_LOGE("%{public}s, Wrong argument count.", __func__);
458         return nullptr;
459     }
460 
461     AsyncZipCallbackInfo *asyncZipCallbackInfo = CreateZipAsyncCallbackInfo(env);
462     if (asyncZipCallbackInfo == nullptr) {
463         return nullptr;
464     }
465 
466     ret = ZipFileWrap(env, info, asyncZipCallbackInfo);
467     return ret;
468 }
469 
ZipFileWrap(napi_env env,napi_callback_info info,AsyncZipCallbackInfo * asyncZipCallbackInfo)470 napi_value ZipFileWrap(napi_env env, napi_callback_info info, AsyncZipCallbackInfo *asyncZipCallbackInfo)
471 {
472     APP_LOGD("%{public}s,called", __func__);
473     napi_value args[ARGS_MAX_COUNT] = {nullptr};
474     napi_value thisArg = nullptr;
475     size_t argcAsync = 4;
476     const size_t argcPromise = 3;
477     NAPI_CALL(env, napi_get_cb_info(env, info, &argcAsync, args, &thisArg, nullptr));
478     if (argcAsync < argcPromise || argcAsync > ARGS_MAX_COUNT) {
479         APP_LOGE("%{public}s, Wrong argument count.", __func__);
480         return nullptr;
481     }
482     if (thisArg == nullptr) {
483         APP_LOGE("%{public}s, This argument is nullptr.", __func__);
484         return nullptr;
485     }
486     napi_valuetype valueTypeOfThis = napi_undefined;
487     NAPI_CALL_BASE(env, napi_typeof(env, thisArg, &valueTypeOfThis), nullptr);
488     if (valueTypeOfThis == napi_undefined) {
489         APP_LOGE("%{public}s, Wrong this value.", __func__);
490         return nullptr;
491     }
492 
493     CallZipUnzipParam param;
494     if (UnwrapZipParam(param, env, args, argcAsync) == nullptr) {
495         APP_LOGE("%{public}s, call unwrapWant failed.", __func__);
496         return nullptr;
497     }
498     napi_value promise = nullptr;
499     std::unique_ptr<AsyncZipCallbackInfo> callbackPtr {asyncZipCallbackInfo};
500     asyncZipCallbackInfo->param = param;
501     if (argcAsync > PARAM3) {
502         napi_valuetype valuetype = napi_undefined;
503         NAPI_CALL_BASE(env, napi_typeof(env, args[PARAM3], &valuetype), nullptr);
504         if (valuetype == napi_function) {
505             napi_ref callbackRef = nullptr;
506             napi_get_undefined(env,  &promise);
507             napi_create_reference(env, args[PARAM3], 1, &callbackRef);
508             asyncZipCallbackInfo->zlibCallbackInfo =
509                 std::make_shared<ZlibCallbackInfo>(env, callbackRef, nullptr, true);
510         }
511     } else {
512         napi_deferred deferred;
513         NAPI_CALL(env, napi_create_promise(env, &deferred, &promise));
514         asyncZipCallbackInfo->zlibCallbackInfo = std::make_shared<ZlibCallbackInfo>(env, nullptr, deferred, false);
515     }
516 
517     CompressExcute(env, asyncZipCallbackInfo);
518     callbackPtr.release();
519     return promise;
520 }
521 
522 /**
523  * @brief Zlib NAPI method : unzipFile.
524  *
525  * @param env The environment that the Node-API call is invoked under.
526  * @param info The callback info passed into the callback function.
527  *
528  * @return The return value from NAPI C++ to JS for the module.
529  */
NAPI_UnzipFile(napi_env env,napi_callback_info info)530 napi_value NAPI_UnzipFile(napi_env env, napi_callback_info info)
531 {
532     napi_value args[ARGS_MAX_COUNT] = {nullptr};
533     size_t argcAsync = 4;
534     size_t argcPromise = 3;
535     NAPI_CALL(env, napi_get_cb_info(env, info, &argcAsync, args, nullptr, nullptr));
536     if (argcAsync < argcPromise || argcAsync > ARGS_MAX_COUNT) {
537         APP_LOGE("%{public}s, Wrong argument count.", __func__);
538         return nullptr;
539     }
540     CallZipUnzipParam param;
541     if (UnwrapUnZipParam(param, env, args, argcAsync) == nullptr) {
542         APP_LOGE("%{public}s, call unwrap param failed.", __func__);
543         return nullptr;
544     }
545     AsyncZipCallbackInfo *asyncZipCallbackInfo = CreateZipAsyncCallbackInfo(env);
546     if (asyncZipCallbackInfo == nullptr) {
547         return nullptr;
548     }
549     std::unique_ptr<AsyncZipCallbackInfo> callbackPtr {asyncZipCallbackInfo};
550     asyncZipCallbackInfo->param = param;
551     napi_value promise = nullptr;
552     if (argcAsync > PARAM3) {
553         napi_valuetype valuetype = napi_undefined;
554         NAPI_CALL_BASE(env, napi_typeof(env, args[PARAM3], &valuetype), nullptr);
555         if (valuetype == napi_function) {
556             napi_ref callbackRef = nullptr;
557             napi_get_undefined(env,  &promise);
558             napi_create_reference(env, args[PARAM3], 1, &callbackRef);
559             asyncZipCallbackInfo->zlibCallbackInfo =
560                 std::make_shared<ZlibCallbackInfo>(env, callbackRef, nullptr, true);
561         }
562     } else {
563         napi_deferred deferred;
564         NAPI_CALL(env, napi_create_promise(env, &deferred, &promise));
565         asyncZipCallbackInfo->zlibCallbackInfo = std::make_shared<ZlibCallbackInfo>(env, nullptr, deferred, false);
566     }
567     DecompressExcute(env, asyncZipCallbackInfo);
568     callbackPtr.release();
569     return promise;
570 }
571 
572 // interface for v9
InitParam(CallZipUnzipParam & param,napi_env env,NapiArg & args,bool isZipFile)573 bool InitParam(CallZipUnzipParam &param, napi_env env, NapiArg &args, bool isZipFile)
574 {
575     if (args.GetMaxArgc() < PARAM2) {
576         return false;
577     }
578     for (size_t i = 0; i < args.GetMaxArgc(); ++i) {
579         napi_valuetype valueType = napi_undefined;
580         napi_typeof(env, args[i], &valueType);
581         if (i == ARGS_POS_ZERO) {
582             if (UnwrapStringParam(param.src, env, args[i]) == nullptr) {
583                 return false;
584             }
585         } else if (i == ARGS_POS_ONE) {
586             if (UnwrapStringParam(param.dest, env, args[i]) == nullptr) {
587                 return false;
588             }
589         } else if (i == ARGS_POS_TWO) {
590             if (isZipFile && valueType != napi_function && !UnwrapOptionsParams(param.options, env, args[i])) {
591                 return false;
592             }
593         } else if (i == ARGS_POS_THREE) {
594             if (valueType == napi_function) {
595                 break;
596             }
597         } else {
598             return false;
599         }
600     }
601     return true;
602 }
603 
CompressExcute(napi_env env,AsyncZipCallbackInfo * asyncZipCallbackInfo)604 void CompressExcute(napi_env env, AsyncZipCallbackInfo *asyncZipCallbackInfo)
605 {
606     if (asyncZipCallbackInfo == nullptr) {
607         APP_LOGE("asyncZipCallbackInfo is nullptr");
608         return;
609     }
610     std::unique_ptr<AsyncZipCallbackInfo> callbackPtr {asyncZipCallbackInfo};
611     if (asyncZipCallbackInfo->zlibCallbackInfo == nullptr) {
612         APP_LOGE("zlibCallbackInfo is nullptr");
613         return;
614     }
615 
616     Zip(asyncZipCallbackInfo->param.src, asyncZipCallbackInfo->param.dest, asyncZipCallbackInfo->param.options,
617         false, asyncZipCallbackInfo->zlibCallbackInfo);
618 }
619 
CompressFile(napi_env env,napi_callback_info info)620 napi_value CompressFile(napi_env env, napi_callback_info info)
621 {
622     APP_LOGD("napi begin CompressFile");
623     NapiArg args(env, info);
624     if (!args.Init(ARGS_SIZE_THREE, ARGS_SIZE_FOUR)) {
625         APP_LOGE("init args failed!");
626         BusinessError::ThrowError(env, ERROR_PARAM_CHECK_ERROR, WRONG_PARAM);
627         return nullptr;
628     }
629     CallZipUnzipParam param;
630     if (!InitParam(param, env, args, true)) {
631         APP_LOGE("Init Param failed!");
632         BusinessError::ThrowError(env, ERROR_PARAM_CHECK_ERROR, WRONG_PARAM);
633         return nullptr;
634     }
635     AsyncZipCallbackInfo *asyncZipCallbackInfo = CreateZipAsyncCallbackInfo(env);
636     if (asyncZipCallbackInfo == nullptr) {
637         APP_LOGE("asyncZipCallbackInfo nullptr!");
638         return nullptr;
639     }
640     asyncZipCallbackInfo->param = param;
641     std::unique_ptr<AsyncZipCallbackInfo> callbackPtr {asyncZipCallbackInfo};
642     asyncZipCallbackInfo->zlibCallbackInfo =
643                 std::make_shared<ZlibCallbackInfo>(env, nullptr, nullptr, false);
644     asyncZipCallbackInfo->zlibCallbackInfo->SetDeliverErrCode(true);
645     if (args.GetMaxArgc() > PARAM3) {
646         napi_valuetype valuetype = napi_undefined;
647         NAPI_CALL_BASE(env, napi_typeof(env, args[PARAM3], &valuetype), nullptr);
648         if (valuetype == napi_function) {
649             napi_ref callbackRef = nullptr;
650             NAPI_CALL(env, napi_create_reference(env, args[PARAM3], NAPI_RETURN_ONE, &callbackRef));
651             asyncZipCallbackInfo->zlibCallbackInfo->SetCallback(callbackRef);
652             asyncZipCallbackInfo->zlibCallbackInfo->SetIsCallback(true);
653         }
654     }
655     napi_value promise = nullptr;
656     if (!asyncZipCallbackInfo->zlibCallbackInfo->GetIsCallback()) {
657         napi_deferred deferred;
658         NAPI_CALL(env, napi_create_promise(env, &deferred, &promise));
659         asyncZipCallbackInfo->zlibCallbackInfo->SetDeferred(deferred);
660     }
661     CompressExcute(env, asyncZipCallbackInfo);
662     callbackPtr.release();
663     return promise;
664 }
665 
DecompressExcute(napi_env env,AsyncZipCallbackInfo * asyncZipCallbackInfo)666 void DecompressExcute(napi_env env, AsyncZipCallbackInfo *asyncZipCallbackInfo)
667 {
668     if (asyncZipCallbackInfo == nullptr) {
669         APP_LOGE("asyncZipCallbackInfo is nullptr");
670         return;
671     }
672     std::unique_ptr<AsyncZipCallbackInfo> callbackPtr {asyncZipCallbackInfo};
673     if (asyncZipCallbackInfo->zlibCallbackInfo == nullptr) {
674         APP_LOGE("zlibCallbackInfo is nullptr");
675         return;
676     }
677     Unzip(asyncZipCallbackInfo->param.src, asyncZipCallbackInfo->param.dest,
678         asyncZipCallbackInfo->param.options, asyncZipCallbackInfo->zlibCallbackInfo);
679 }
680 
DecompressFile(napi_env env,napi_callback_info info)681 napi_value DecompressFile(napi_env env, napi_callback_info info)
682 {
683     APP_LOGD("napi begin CompressFile");
684     NapiArg args(env, info);
685     if (!args.Init(ARGS_SIZE_TWO, ARGS_SIZE_FOUR)) {
686         BusinessError::ThrowError(env, ERROR_PARAM_CHECK_ERROR, WRONG_PARAM);
687         return nullptr;
688     }
689     CallZipUnzipParam param;
690     if (!InitParam(param, env, args, true)) {
691         BusinessError::ThrowError(env, ERROR_PARAM_CHECK_ERROR, WRONG_PARAM);
692         return nullptr;
693     }
694     AsyncZipCallbackInfo *asyncZipCallbackInfo = CreateZipAsyncCallbackInfo(env);
695     if (asyncZipCallbackInfo == nullptr) {
696         return nullptr;
697     }
698     asyncZipCallbackInfo->param = param;
699     std::unique_ptr<AsyncZipCallbackInfo> callbackPtr {asyncZipCallbackInfo};
700     asyncZipCallbackInfo->zlibCallbackInfo =
701                 std::make_shared<ZlibCallbackInfo>(env, nullptr, nullptr, false);
702     asyncZipCallbackInfo->zlibCallbackInfo->SetDeliverErrCode(true);
703     for (size_t i = PARAM2; i < args.GetMaxArgc(); i++) {
704         napi_valuetype valuetype = napi_undefined;
705         NAPI_CALL_BASE(env, napi_typeof(env, args[i], &valuetype), nullptr);
706         if (valuetype == napi_function) {
707             napi_ref callbackRef = nullptr;
708             NAPI_CALL(env, napi_create_reference(env, args[i], NAPI_RETURN_ONE, &callbackRef));
709             asyncZipCallbackInfo->zlibCallbackInfo->SetCallback(callbackRef);
710             asyncZipCallbackInfo->zlibCallbackInfo->SetIsCallback(true);
711             break;
712         }
713     }
714     napi_value promise = nullptr;
715     if (!asyncZipCallbackInfo->zlibCallbackInfo->GetIsCallback()) {
716         napi_deferred deferred;
717         NAPI_CALL(env, napi_create_promise(env, &deferred, &promise));
718         asyncZipCallbackInfo->zlibCallbackInfo->SetDeferred(deferred);
719     }
720     DecompressExcute(env, asyncZipCallbackInfo);
721     callbackPtr.release();
722     return promise;
723 }
724 
725 }  // namespace LIBZIP
726 }  // namespace AppExecFwk
727 }  // namespace OHOS
728