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 ¶m, napi_env env, napi_value *args, size_t argc);
71 napi_value UnwrapUnZipParam(CallZipUnzipParam ¶m, 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 ¶m, 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 ¶m, 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 ¶m, 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