1 /*
2  * Copyright (c) 2022-2023 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 "common_func.h"
17 
18 #include <dirent.h>
19 #include <fcntl.h>
20 #include <memory>
21 #include <sstream>
22 #include <sys/stat.h>
23 #include <sys/types.h>
24 #include <unistd.h>
25 #include <vector>
26 
27 #include "app_log_wrapper.h"
28 #include "gzip_entity.h"
29 #include "napi_class.h"
30 #include "napi_business_error.h"
31 #include "zip_entity.h"
32 
33 namespace OHOS {
34 namespace AppExecFwk {
35 namespace LIBZIP {
36 using namespace std;
37 
38 static constexpr uint8_t MIN_NUMBER = 1;
39 static constexpr uint8_t MIN_ASCII = 0;
40 static constexpr uint8_t MAX_ASCII = 255;
41 static constexpr uint8_t MIN_WINDOWBITS = 8;
42 static constexpr uint8_t MAX_WINDOWBITS = 15;
43 
GetAdler32Arg(napi_env env,const NapiFuncArg & funcArg)44 tuple<bool, int64_t, void *, size_t> CommonFunc::GetAdler32Arg(napi_env env, const NapiFuncArg &funcArg)
45 {
46     bool succ = false;
47     int64_t adler = 0U;
48 
49     // The first argument
50     NapiValue adlerNVal(env, funcArg[ArgumentPosition::FIRST]);
51     tie(succ, adler) = adlerNVal.ToInt64();
52     if (!succ) {
53         NapiBusinessError().ThrowErr(env, EINVAL);
54         return {false, 0, nullptr, 0};
55     }
56 
57     // The second argument
58     NapiValue bufNVal(env, funcArg[ArgumentPosition::SECOND]);
59     void *buf = nullptr;
60     size_t bufLen = 0;
61     tie(succ, buf, bufLen) = bufNVal.ToArrayBuffer();
62     if (!succ) {
63         NapiBusinessError().ThrowErr(env, EINVAL);
64         return {false, 0, nullptr, 0};
65     }
66 
67     return {true, adler, buf, bufLen};
68 }
69 
GetCrc64Arg(napi_env env,const NapiFuncArg & funcArg)70 tuple<bool, int64_t, void *, size_t> CommonFunc::GetCrc64Arg(napi_env env, const NapiFuncArg &funcArg)
71 {
72     bool succ = false;
73     int64_t crc64 = 0U;
74 
75     // The first argument
76     NapiValue crc64NVal(env, funcArg[ArgumentPosition::FIRST]);
77     tie(succ, crc64) = crc64NVal.ToInt64();
78     if (!succ) {
79         NapiBusinessError().ThrowErr(env, EINVAL);
80         return {false, 0, nullptr, 0};
81     }
82 
83     // The second argument
84     NapiValue bufNVal(env, funcArg[ArgumentPosition::SECOND]);
85     void *buf = nullptr;
86     size_t bufLen = 0;
87     tie(succ, buf, bufLen) = bufNVal.ToArrayBuffer();
88     if (!succ) {
89         NapiBusinessError().ThrowErr(env, EINVAL);
90         return {false, 0, nullptr, 0};
91     }
92 
93     return {true, crc64, buf, bufLen};
94 }
95 
GetAdler32CombineArg(napi_env env,const NapiFuncArg & funcArg)96 tuple<bool, unsigned long, unsigned long, int64_t> CommonFunc::GetAdler32CombineArg(
97     napi_env env, const NapiFuncArg &funcArg)
98 {
99     bool succ = false;
100     uint64_t adler1 = 0U;
101     uint64_t adler2 = 0U;
102     int64_t len = 0;
103 
104     NapiValue adler1NVal(env, funcArg[ArgumentPosition::FIRST]);
105     tie(succ, adler1) = adler1NVal.ToInt64();
106     if (!succ) {
107         NapiBusinessError().ThrowErr(env, EINVAL);
108         return {false, 0, 0, 0};
109     }
110 
111     NapiValue adler2NVal(env, funcArg[ArgumentPosition::SECOND]);
112     tie(succ, adler2) = adler2NVal.ToInt64();
113     if (!succ) {
114         NapiBusinessError().ThrowErr(env, EINVAL);
115         return {false, 0, 0, 0};
116     }
117 
118     NapiValue bufLenNVal(env, funcArg[ArgumentPosition::THIRD]);
119     tie(succ, len) = bufLenNVal.ToInt64();
120     if (!succ || len < 0) {
121         NapiBusinessError().ThrowErr(env, EINVAL);
122         return {false, 0, 0, 0};
123     }
124     return {true, adler1, adler2, len};
125 }
126 
SetZStreamOutValue(const HasZStreamMember & hasZStreamMember,ZipEntity * zipEntity,const z_stream & zs)127 static void SetZStreamOutValue(const HasZStreamMember &hasZStreamMember, ZipEntity *zipEntity, const z_stream &zs)
128 {
129     if (hasZStreamMember.hasNextOut) {
130         zipEntity->zs.get()->next_out = zs.next_out;
131     }
132     if (hasZStreamMember.hasAvailOut) {
133         zipEntity->zs.get()->avail_out = zs.avail_out;
134     }
135     if (hasZStreamMember.hasTotalOut) {
136         zipEntity->zs.get()->total_out = zs.total_out;
137     }
138     if (hasZStreamMember.hasDataType) {
139         zipEntity->zs.get()->data_type = zs.data_type;
140     }
141     if (hasZStreamMember.hasAdler) {
142         zipEntity->zs.get()->adler = zs.adler;
143     }
144 }
145 
SetZStreamValue(napi_env env,const NapiFuncArg & funcArg)146 bool CommonFunc::SetZStreamValue(napi_env env, const NapiFuncArg &funcArg)
147 {
148     /* To get entity */
149     auto zipEntity = NapiClass::GetEntityOf<ZipEntity>(env, funcArg.GetThisVar());
150     if (!zipEntity) {
151         NapiBusinessError().ThrowErr(env, EFAULT);
152         return false;
153     }
154 
155     bool succ = false;
156     z_stream zs = {};
157     HasZStreamMember hasZStreamMember;
158     tie(succ, zs, hasZStreamMember) = CommonFunc::GetZstreamArg(env, funcArg[ArgumentPosition::FIRST]);
159     if (!succ) {
160         NapiBusinessError().ThrowErr(env, EINVAL);
161         return succ;
162     }
163 
164     if (!zipEntity->zs) {
165         zipEntity->zs = std::make_unique<z_stream>();
166     }
167 
168     if (hasZStreamMember.hasNextIn) {
169         zipEntity->zs.get()->next_in = zs.next_in;
170     }
171     if (hasZStreamMember.hasAvailIn) {
172         zipEntity->zs.get()->avail_in = zs.avail_in;
173     }
174     if (hasZStreamMember.hasTotalIn) {
175         zipEntity->zs.get()->total_in = zs.total_in;
176     }
177 
178     SetZStreamOutValue(hasZStreamMember, zipEntity, zs);
179     return succ;
180 }
181 
GetZStreamInValue(napi_env env,NapiValue zstreamNVal,HasZStreamMember & hasZStreamMember,z_stream & zs)182 static bool GetZStreamInValue(napi_env env, NapiValue zstreamNVal, HasZStreamMember &hasZStreamMember, z_stream &zs)
183 {
184     bool succ = false;
185     if (zstreamNVal.HasProp("nextIn") && !zstreamNVal.GetProp("nextIn").TypeIs(napi_undefined) &&
186         !zstreamNVal.GetProp("nextIn").TypeIs(napi_null)) {
187         void *buf = nullptr;
188         size_t bufLen = 0;
189         tie(succ, buf, bufLen) = zstreamNVal.GetProp("nextIn").ToArrayBuffer();
190         if (!succ) {
191             NapiBusinessError().ThrowErr(env, EINVAL);
192             return false;
193         }
194         zs.next_in = reinterpret_cast<Bytef *>(buf);
195         hasZStreamMember.hasNextIn = true;
196     }
197 
198     if (zstreamNVal.HasProp("availableIn") && !zstreamNVal.GetProp("availableIn").TypeIs(napi_undefined) &&
199         !zstreamNVal.GetProp("availableIn").TypeIs(napi_null)) {
200         uint32_t availableIn = 0U;
201         tie(succ, availableIn) = zstreamNVal.GetProp("availableIn").ToInt32();
202         if (!succ) {
203             NapiBusinessError().ThrowErr(env, EINVAL);
204             return false;
205         }
206         zs.avail_in = availableIn;
207         hasZStreamMember.hasAvailIn = true;
208     }
209 
210     if (zstreamNVal.HasProp("totalIn") && !zstreamNVal.GetProp("totalIn").TypeIs(napi_undefined) &&
211         !zstreamNVal.GetProp("totalIn").TypeIs(napi_null)) {
212         uint64_t totalIn = 0U;
213         tie(succ, totalIn) = zstreamNVal.GetProp("totalIn").ToInt64();
214         if (!succ) {
215             NapiBusinessError().ThrowErr(env, EINVAL);
216             return false;
217         }
218         zs.total_in = totalIn;
219         hasZStreamMember.hasTotalIn = true;
220     }
221 
222     return true;
223 }
224 
GetZStreamOtherValue(napi_env env,NapiValue zstreamNVal,HasZStreamMember & hasZStreamMember,z_stream & zs)225 static bool GetZStreamOtherValue(napi_env env, NapiValue zstreamNVal, HasZStreamMember &hasZStreamMember, z_stream &zs)
226 {
227     bool succ = false;
228     if (zstreamNVal.HasProp("dataType") && !zstreamNVal.GetProp("dataType").TypeIs(napi_undefined) &&
229         !zstreamNVal.GetProp("dataType").TypeIs(napi_null)) {
230         int32_t dataType = 0;
231         tie(succ, dataType) = zstreamNVal.GetProp("dataType").ToInt32();
232         if (!succ) {
233             NapiBusinessError().ThrowErr(env, EINVAL);
234             return false;
235         }
236         zs.data_type = dataType;
237         hasZStreamMember.hasDataType = true;
238     }
239 
240     if (zstreamNVal.HasProp("adler") && !zstreamNVal.GetProp("adler").TypeIs(napi_undefined) &&
241         !zstreamNVal.GetProp("adler").TypeIs(napi_null)) {
242         uint64_t adler = 0;
243         tie(succ, adler) = zstreamNVal.GetProp("adler").ToInt64();
244         if (!succ) {
245             NapiBusinessError().ThrowErr(env, EINVAL);
246             return false;
247         }
248         zs.adler = adler;
249         hasZStreamMember.hasAdler = true;
250     }
251 
252     return true;
253 }
254 
GetZstreamArg(napi_env env,napi_value zstream)255 std::tuple<bool, z_stream, HasZStreamMember> CommonFunc::GetZstreamArg(napi_env env, napi_value zstream)
256 {
257     z_stream zs = {};
258     bool succ = false;
259     NapiValue zstreamNVal(env, zstream);
260     HasZStreamMember hasZStreamMember = {};
261 
262     if (zstreamNVal.TypeIs(napi_undefined) || zstreamNVal.TypeIs(napi_null)) {
263         NapiBusinessError().ThrowErr(env, EINVAL);
264         return { false, {}, {} };
265     }
266 
267     succ = GetZStreamInValue(env, zstreamNVal, hasZStreamMember, zs);
268     if (!succ) {
269         NapiBusinessError().ThrowErr(env, EINVAL);
270         return { false, {}, {} };
271     }
272 
273     if (zstreamNVal.HasProp("nextOut") && !zstreamNVal.GetProp("nextOut").TypeIs(napi_undefined) &&
274         !zstreamNVal.GetProp("nextOut").TypeIs(napi_null)) {
275         void *buf = nullptr;
276         size_t bufLen = 0;
277         tie(succ, buf, bufLen) = zstreamNVal.GetProp("nextOut").ToArrayBuffer();
278         if (!succ) {
279             NapiBusinessError().ThrowErr(env, EINVAL);
280             return {false, {}, {}};
281         }
282         zs.next_out = reinterpret_cast<Bytef *>(buf);
283         hasZStreamMember.hasNextOut = true;
284     }
285 
286     if (zstreamNVal.HasProp("availableOut") && !zstreamNVal.GetProp("availableOut").TypeIs(napi_undefined) &&
287         !zstreamNVal.GetProp("availableOut").TypeIs(napi_null)) {
288         uint32_t availableOut = 0U;
289         tie(succ, availableOut) = zstreamNVal.GetProp("availableOut").ToInt32();
290         if (!succ) {
291             NapiBusinessError().ThrowErr(env, EINVAL);
292             return {false, {}, {}};
293         }
294         zs.avail_out = availableOut;
295         hasZStreamMember.hasAvailOut = true;
296     }
297 
298     if (zstreamNVal.HasProp("totalOut") && !zstreamNVal.GetProp("totalOut").TypeIs(napi_undefined) &&
299         !zstreamNVal.GetProp("totalOut").TypeIs(napi_null)) {
300         uint64_t totalOut = 0U;
301         tie(succ, totalOut) = zstreamNVal.GetProp("totalOut").ToInt64();
302         if (!succ) {
303             NapiBusinessError().ThrowErr(env, EINVAL);
304             return {false, {}, {}};
305         }
306         zs.total_out = totalOut;
307         hasZStreamMember.hasTotalOut = true;
308     }
309 
310     succ = GetZStreamOtherValue(env, zstreamNVal, hasZStreamMember, zs);
311     if (!succ) {
312         NapiBusinessError().ThrowErr(env, EINVAL);
313         return { false, {}, {} };
314     }
315 
316     return {true, zs, hasZStreamMember};
317 }
318 
GetGZHeadValue(napi_env env,const NapiValue & gzHeaderNVal,gz_header & gzHeader)319 static bool GetGZHeadValue(napi_env env, const NapiValue &gzHeaderNVal, gz_header &gzHeader)
320 {
321     bool succ = false;
322     if (gzHeaderNVal.HasProp("isText") && !gzHeaderNVal.GetProp("isText").TypeIs(napi_undefined) &&
323         !gzHeaderNVal.GetProp("isText").TypeIs(napi_null)) {
324         bool text = false;
325         tie(succ, text) = gzHeaderNVal.GetProp("isText").ToBool();
326         if (!succ) {
327             NapiBusinessError().ThrowErr(env, EINVAL);
328             return false;
329         }
330         gzHeader.text = text;
331     }
332 
333     if (gzHeaderNVal.HasProp("time") && !gzHeaderNVal.GetProp("time").TypeIs(napi_undefined) &&
334         !gzHeaderNVal.GetProp("time").TypeIs(napi_null)) {
335         uint64_t time = 0U;
336         tie(succ, time) = gzHeaderNVal.GetProp("time").ToInt64();
337         if (!succ) {
338             NapiBusinessError().ThrowErr(env, EINVAL);
339             return false;
340         }
341         gzHeader.time = time;
342     }
343 
344     if (gzHeaderNVal.HasProp("xflags") && !gzHeaderNVal.GetProp("xflags").TypeIs(napi_undefined) &&
345         !gzHeaderNVal.GetProp("xflags").TypeIs(napi_null)) {
346         int32_t xflags = 0;
347         tie(succ, xflags) = gzHeaderNVal.GetProp("xflags").ToInt32();
348         if (!succ) {
349             NapiBusinessError().ThrowErr(env, EINVAL);
350             return false;
351         }
352         gzHeader.xflags = xflags;
353     }
354 
355     if (gzHeaderNVal.HasProp("os") && !gzHeaderNVal.GetProp("os").TypeIs(napi_undefined) &&
356         !gzHeaderNVal.GetProp("os").TypeIs(napi_null)) {
357         int32_t os = 0;
358         tie(succ, os) = gzHeaderNVal.GetProp("os").ToInt32();
359         if (!succ) {
360             NapiBusinessError().ThrowErr(env, EINVAL);
361             return false;
362         }
363         gzHeader.os = os;
364     }
365     return true;
366 }
367 
UnwrapGZHeadValue(napi_env env,NapiValue & gzHeaderNVal,gz_header & gzHeader)368 static bool UnwrapGZHeadValue(napi_env env, NapiValue &gzHeaderNVal, gz_header &gzHeader)
369 {
370     bool succ = false;
371     if (gzHeaderNVal.HasProp("extra") && !gzHeaderNVal.GetProp("extra").TypeIs(napi_undefined) &&
372         !gzHeaderNVal.GetProp("extra").TypeIs(napi_null)) {
373         void *extra = nullptr;
374         size_t extraLen = 0;
375         tie(succ, extra, extraLen) = gzHeaderNVal.GetProp("extra").ToArrayBuffer();
376         if (!succ) {
377             NapiBusinessError().ThrowErr(env, EINVAL);
378             return false;
379         }
380         gzHeader.extra = reinterpret_cast<Bytef *>(extra);
381     }
382 
383     if (gzHeaderNVal.HasProp("done") && !gzHeaderNVal.GetProp("done").TypeIs(napi_undefined) &&
384         !gzHeaderNVal.GetProp("done").TypeIs(napi_null)) {
385         bool done = false;
386         tie(succ, done) = gzHeaderNVal.GetProp("done").ToBool();
387         if (!succ) {
388             NapiBusinessError().ThrowErr(env, EINVAL);
389             return false;
390         }
391         gzHeader.done = done;
392     }
393 
394     if (gzHeaderNVal.HasProp("hcrc") && !gzHeaderNVal.GetProp("hcrc").TypeIs(napi_undefined) &&
395         !gzHeaderNVal.GetProp("hcrc").TypeIs(napi_null)) {
396         bool hcrc = false;
397         tie(succ, hcrc) = gzHeaderNVal.GetProp("hcrc").ToBool();
398         if (!succ) {
399             NapiBusinessError().ThrowErr(env, EINVAL);
400             return false;
401         }
402         gzHeader.hcrc = hcrc;
403     }
404 
405     return true;
406 }
407 
GetGZHeaderArg(napi_env env,napi_value argGZheader)408 std::tuple<bool, gz_header> CommonFunc::GetGZHeaderArg(napi_env env, napi_value argGZheader)
409 {
410     bool succ = false;
411     NapiValue gzHeaderNVal(env, argGZheader);
412     gz_header gzHeader = {};
413 
414     if (gzHeaderNVal.TypeIs(napi_undefined) || gzHeaderNVal.TypeIs(napi_null)) {
415         NapiBusinessError().ThrowErr(env, EINVAL);
416         return { false, {}};
417     }
418 
419     succ = GetGZHeadValue(env, gzHeaderNVal, gzHeader);
420     if (!succ) {
421         NapiBusinessError().ThrowErr(env, EINVAL);
422         return { false, {} };
423     }
424 
425     if (gzHeaderNVal.HasProp("extraLen") && !gzHeaderNVal.GetProp("extraLen").TypeIs(napi_undefined) &&
426         !gzHeaderNVal.GetProp("extraLen").TypeIs(napi_null)) {
427         uint32_t extraLen = 0U;
428         tie(succ, extraLen) = gzHeaderNVal.GetProp("extraLen").ToInt32();
429         if (!succ) {
430             NapiBusinessError().ThrowErr(env, EINVAL);
431             return {false, {}};
432         }
433         gzHeader.extra_len = extraLen;
434     }
435 
436     if (gzHeaderNVal.HasProp("name") && !gzHeaderNVal.GetProp("name").TypeIs(napi_undefined) &&
437         !gzHeaderNVal.GetProp("name").TypeIs(napi_null)) {
438         void *name = nullptr;
439         size_t nameLen = 0;
440         tie(succ, name, nameLen) = gzHeaderNVal.GetProp("name").ToArrayBuffer();
441         if (!succ) {
442             NapiBusinessError().ThrowErr(env, EINVAL);
443             return {false, {}};
444         }
445         gzHeader.name = reinterpret_cast<Bytef *>(name);
446     }
447 
448     if (gzHeaderNVal.HasProp("comment") && !gzHeaderNVal.GetProp("comment").TypeIs(napi_undefined) &&
449         !gzHeaderNVal.GetProp("comment").TypeIs(napi_null)) {
450         void *comment = nullptr;
451         size_t commentLen = 0;
452         tie(succ, comment, commentLen) = gzHeaderNVal.GetProp("comment").ToArrayBuffer();
453         if (!succ) {
454             NapiBusinessError().ThrowErr(env, EINVAL);
455             return {false, {}};
456         }
457         gzHeader.comment = reinterpret_cast<Bytef *>(comment);
458     }
459 
460     succ = UnwrapGZHeadValue(env, gzHeaderNVal, gzHeader);
461     if (!succ) {
462         NapiBusinessError().ThrowErr(env, EINVAL);
463         return { false, {} };
464     }
465 
466     return {true, gzHeader};
467 }
468 
GetInflateInitArg(napi_env env,const NapiFuncArg & funcArg)469 std::tuple<bool, z_stream, int32_t> CommonFunc::GetInflateInitArg(napi_env env, const NapiFuncArg &funcArg)
470 {
471     bool succ = false;
472 
473     // The first argument
474     z_stream zs = {};
475     HasZStreamMember hasZStreamMember = {};
476     tie(succ, zs, hasZStreamMember) = GetZstreamArg(env, funcArg[ArgumentPosition::FIRST]);
477     if (!succ) {
478         NapiBusinessError().ThrowErr(env, EINVAL);
479         return {false, {}, 0};
480     }
481 
482     // The second argument
483     NapiValue bufNVal(env, funcArg[ArgumentPosition::SECOND]);
484     int32_t windowBits = 0;
485     tie(succ, windowBits) = bufNVal.ToInt32();
486     if (!succ) {
487         NapiBusinessError().ThrowErr(env, EINVAL);
488         return {false, {}, 0};
489     }
490 
491     return {true, zs, windowBits};
492 }
493 
GetDeflateInitArg(napi_env env,const NapiFuncArg & funcArg)494 std::tuple<bool, z_stream, int32_t> CommonFunc::GetDeflateInitArg(napi_env env, const NapiFuncArg &funcArg)
495 {
496     bool succ = false;
497 
498     // The first argument
499     z_stream zs = {};
500     HasZStreamMember hasZStreamMember = {};
501     tie(succ, zs, hasZStreamMember) = GetZstreamArg(env, funcArg[ArgumentPosition::FIRST]);
502     if (!succ) {
503         NapiBusinessError().ThrowErr(env, EINVAL);
504         return {false, {}, 0};
505     }
506 
507     // The second argument
508     NapiValue levelNVal(env, funcArg[ArgumentPosition::SECOND]);
509     int32_t level = 0;
510     tie(succ, level) = levelNVal.ToInt32();
511     if (!succ) {
512         NapiBusinessError().ThrowErr(env, EINVAL);
513         return {false, {}, 0};
514     }
515 
516     return {true, zs, level};
517 }
518 
GetDeflateInit2Arg(napi_env env,const NapiFuncArg & funcArg)519 std::tuple<bool, z_stream, int32_t, int32_t, int32_t, int32_t, int32_t> CommonFunc::GetDeflateInit2Arg(
520     napi_env env, const NapiFuncArg &funcArg)
521 {
522     bool succ = false;
523 
524     // The first argument
525     z_stream zs = {};
526     HasZStreamMember hasZStreamMember = {};
527     tie(succ, zs, hasZStreamMember) = GetZstreamArg(env, funcArg[ArgumentPosition::FIRST]);
528     if (!succ) {
529         NapiBusinessError().ThrowErr(env, EINVAL);
530         return {false, {}, 0, 0, 0, 0, 0};
531     }
532 
533     // The second argument
534     NapiValue levelNVal(env, funcArg[ArgumentPosition::SECOND]);
535     int32_t level = 0;
536     tie(succ, level) = levelNVal.ToInt32();
537     if (!succ) {
538         NapiBusinessError().ThrowErr(env, EINVAL);
539         return {false, {}, 0, 0, 0, 0, 0};
540     }
541 
542     // The third argument
543     NapiValue methodNVal(env, funcArg[ArgumentPosition::THIRD]);
544     int32_t method = 0;
545     tie(succ, method) = methodNVal.ToInt32();
546     if (!succ) {
547         NapiBusinessError().ThrowErr(env, EINVAL);
548         return {false, {}, 0, 0, 0, 0, 0};
549     }
550 
551     // The fourth argument
552     NapiValue windowBitsNVal(env, funcArg[ArgumentPosition::FOURTH]);
553     int32_t windowBits = 0;
554     tie(succ, windowBits) = windowBitsNVal.ToInt32();
555     if (!succ) {
556         NapiBusinessError().ThrowErr(env, EINVAL);
557         return {false, {}, 0, 0, 0, 0, 0};
558     }
559 
560     // The fifth argument
561     NapiValue memLevelNVal(env, funcArg[ArgumentPosition::FIFTH]);
562     int32_t memLevel = 0;
563     tie(succ, memLevel) = memLevelNVal.ToInt32();
564     if (!succ) {
565         NapiBusinessError().ThrowErr(env, EINVAL);
566         return {false, {}, 0, 0, 0, 0, 0};
567     }
568 
569     // The sixth argument
570     NapiValue strategyNVal(env, funcArg[ArgumentPosition::SIXTH]);
571     int32_t strategy = 0;
572     tie(succ, strategy) = strategyNVal.ToInt32();
573     if (!succ) {
574         NapiBusinessError().ThrowErr(env, EINVAL);
575         return {false, {}, 0, 0, 0, 0, 0};
576     }
577 
578     return {true, zs, level, method, windowBits, memLevel, strategy};
579 }
580 
GetDeflateArg(napi_env env,const NapiFuncArg & funcArg)581 std::tuple<bool, int32_t> CommonFunc::GetDeflateArg(napi_env env, const NapiFuncArg &funcArg)
582 {
583     // The first argument
584     bool succ = CommonFunc::SetZStreamValue(env, funcArg);
585     if (!succ) {
586         return {false, 0};
587     }
588 
589     // The second argument
590     NapiValue flushNVal(env, funcArg[ArgumentPosition::SECOND]);
591     int32_t flush = 0;
592     tie(succ, flush) = flushNVal.ToInt32();
593     if (!succ) {
594         NapiBusinessError().ThrowErr(env, EINVAL);
595         return {false, 0};
596     }
597 
598     return {true, flush};
599 }
600 
GetCompressArg(napi_env env,const NapiFuncArg & funcArg)601 std::tuple<bool, void *, size_t, void *, int64_t> CommonFunc::GetCompressArg(napi_env env, const NapiFuncArg &funcArg)
602 {
603     bool succ = false;
604     void *dest = nullptr;
605     size_t destLen = 0;
606     NapiValue destNVal(env, funcArg[ArgumentPosition::FIRST]);
607     tie(succ, dest, destLen) = destNVal.ToArrayBuffer();
608     if (!succ) {
609         NapiBusinessError().ThrowErr(env, EINVAL);
610         return {false, nullptr, 0, nullptr, 0};
611     }
612 
613     void *source = nullptr;
614     int64_t sourceLen = 0;
615     NapiValue sourceNVal(env, funcArg[ArgumentPosition::SECOND]);
616     tie(succ, source, sourceLen) = sourceNVal.ToArrayBuffer();
617     if (!succ) {
618         NapiBusinessError().ThrowErr(env, EINVAL);
619         return {false, nullptr, 0, nullptr, 0};
620     }
621 
622     if (funcArg.GetArgc() == ArgumentCount::THREE) {
623         int64_t sourceLenIn = 0;
624         NapiValue sourceLenNVal(env, funcArg[ArgumentPosition::THIRD]);
625         tie(succ, sourceLenIn) = sourceLenNVal.ToInt64(sourceLen);
626         if (!succ || sourceLenIn < 0) {
627             NapiBusinessError().ThrowErr(env, EINVAL);
628             return { false, nullptr, 0, nullptr, 0 };
629         }
630         sourceLen = sourceLenIn;
631     }
632 
633     return {true, dest, destLen, source, sourceLen};
634 }
635 
GetCompress2Arg(napi_env env,const NapiFuncArg & funcArg)636 std::tuple<bool, void *, size_t, void *, size_t, int32_t> CommonFunc::GetCompress2Arg(
637     napi_env env, const NapiFuncArg &funcArg)
638 {
639     bool succ = false;
640     void *dest = nullptr;
641     size_t destLen = 0;
642     NapiValue destNVal(env, funcArg[ArgumentPosition::FIRST]);
643     tie(succ, dest, destLen) = destNVal.ToArrayBuffer();
644     if (!succ) {
645         NapiBusinessError().ThrowErr(env, EINVAL);
646         return {false, nullptr, 0, nullptr, 0, 0};
647     }
648 
649     void *source = nullptr;
650     int64_t sourceLen = 0;
651     NapiValue sourceNVal(env, funcArg[ArgumentPosition::SECOND]);
652     tie(succ, source, sourceLen) = sourceNVal.ToArrayBuffer();
653     if (!succ) {
654         NapiBusinessError().ThrowErr(env, EINVAL);
655         return {false, nullptr, 0, nullptr, 0, 0};
656     }
657 
658     int32_t level = 0;
659     NapiValue levelNVal(env, funcArg[ArgumentPosition::THIRD]);
660     tie(succ, level) = levelNVal.ToInt32();
661     if (!succ) {
662         NapiBusinessError().ThrowErr(env, EINVAL);
663         return {false, nullptr, 0, nullptr, 0, 0};
664     }
665 
666     if (funcArg.GetArgc() == ArgumentCount::FOUR) {
667         int64_t sourceLenIn = 0;
668         NapiValue sourceLenNVal(env, funcArg[ArgumentPosition::FOURTH]);
669         tie(succ, sourceLenIn) = sourceLenNVal.ToInt64(sourceLen);
670         if (!succ || sourceLenIn < 0) {
671             NapiBusinessError().ThrowErr(env, EINVAL);
672             return {false, nullptr, 0, nullptr, 0, 0};
673         }
674         sourceLen = sourceLenIn;
675     }
676 
677     return {true, dest, destLen, source, sourceLen, level};
678 }
679 
GetUnCompressArg(napi_env env,const NapiFuncArg & funcArg)680 std::tuple<bool, void *, size_t, void *, int64_t> CommonFunc::GetUnCompressArg(napi_env env, const NapiFuncArg &funcArg)
681 {
682     bool succ = false;
683     void *dest = nullptr;
684     size_t destLen = 0;
685     NapiValue destNVal(env, funcArg[ArgumentPosition::FIRST]);
686     tie(succ, dest, destLen) = destNVal.ToArrayBuffer();
687     if (!succ) {
688         NapiBusinessError().ThrowErr(env, EINVAL);
689         return {false, nullptr, 0, nullptr, 0};
690     }
691 
692     void *source = nullptr;
693     int64_t sourceLen = 0;
694     NapiValue sourceNVal(env, funcArg[ArgumentPosition::SECOND]);
695     tie(succ, source, sourceLen) = sourceNVal.ToArrayBuffer();
696     if (!succ) {
697         NapiBusinessError().ThrowErr(env, EINVAL);
698         return {false, nullptr, 0, nullptr, 0};
699     }
700 
701     if (funcArg.GetArgc() == ArgumentCount::THREE) {
702         int64_t sourceLenIn = 0;
703         NapiValue sourceLenNVal(env, funcArg[ArgumentPosition::THIRD]);
704         tie(succ, sourceLenIn) = sourceLenNVal.ToInt64(sourceLen);
705         if (!succ || sourceLenIn < 0) {
706             NapiBusinessError().ThrowErr(env, EINVAL);
707             return { false, nullptr, 0, nullptr, 0 };
708         }
709         sourceLen = sourceLenIn;
710     }
711 
712     return {true, dest, destLen, source, sourceLen};
713 }
714 
GetZErrorArg(napi_env env,const NapiFuncArg & funcArg)715 std::tuple<bool, int32_t> CommonFunc::GetZErrorArg(napi_env env, const NapiFuncArg &funcArg)
716 {
717     bool succ = false;
718     NapiValue errNVal(env, funcArg[ArgumentPosition::FIRST]);
719     int32_t zlibError = 0;
720     tie(succ, zlibError) = errNVal.ToInt32();
721     if (!succ) {
722         NapiBusinessError().ThrowErr(env, EINVAL);
723         return {false, 0};
724     }
725 
726     return {true, zlibError};
727 }
728 
GetInflateSetDictionaryArg(napi_env env,const NapiFuncArg & funcArg)729 std::tuple<bool, void *, size_t> CommonFunc::GetInflateSetDictionaryArg(napi_env env, const NapiFuncArg &funcArg)
730 {
731     bool succ = CommonFunc::SetZStreamValue(env, funcArg);
732     if (!succ) {
733         NapiBusinessError().ThrowErr(env, EINVAL);
734         return {false, nullptr, 0};
735     }
736 
737     NapiValue bufNVal(env, funcArg[ArgumentPosition::SECOND]);
738     void *buf = nullptr;
739     size_t bufLen = 0;
740     tie(succ, buf, bufLen) = bufNVal.ToArrayBuffer();
741     if (!succ) {
742         NapiBusinessError().ThrowErr(env, EINVAL);
743         return {false, nullptr, 0};
744     }
745 
746     return {true, buf, bufLen};
747 }
748 
GetInflateArg(napi_env env,const NapiFuncArg & funcArg)749 std::tuple<bool, int32_t> CommonFunc::GetInflateArg(napi_env env, const NapiFuncArg &funcArg)
750 {
751     bool succ = CommonFunc::SetZStreamValue(env, funcArg);
752     if (!succ) {
753         NapiBusinessError().ThrowErr(env, EINVAL);
754         return {false, 0};
755     }
756 
757     NapiValue flushNVal(env, funcArg[ArgumentPosition::SECOND]);
758     int32_t flush = 0;
759     tie(succ, flush) = flushNVal.ToInt32();
760     if (!succ) {
761         NapiBusinessError().ThrowErr(env, EINVAL);
762         return {false, 0};
763     }
764 
765     return {true, flush};
766 }
767 
GetInflateReset2Arg(napi_env env,const NapiFuncArg & funcArg)768 std::tuple<bool, int32_t> CommonFunc::GetInflateReset2Arg(napi_env env, const NapiFuncArg &funcArg)
769 {
770     bool succ = CommonFunc::SetZStreamValue(env, funcArg);
771     if (!succ) {
772         NapiBusinessError().ThrowErr(env, EINVAL);
773         return {false, 0};
774     }
775 
776     NapiValue flushNVal(env, funcArg[ArgumentPosition::SECOND]);
777     int32_t flush = 0;
778     tie(succ, flush) = flushNVal.ToInt32();
779     if (!succ) {
780         NapiBusinessError().ThrowErr(env, EINVAL);
781         return {false, 0};
782     }
783 
784     return {true, flush};
785 }
786 
GetInflateBackInitArg(napi_env env,const NapiFuncArg & funcArg)787 std::tuple<bool, unsigned long, void*, size_t> CommonFunc::GetInflateBackInitArg(
788     napi_env env, const NapiFuncArg& funcArg)
789 {
790     bool succ = CommonFunc::SetZStreamValue(env, funcArg);
791     if (!succ) {
792         NapiBusinessError().ThrowErr(env, EINVAL);
793         return {false, 0, nullptr, 0};
794     }
795 
796     int32_t windowBits = 0;
797     NapiValue windowBitsNVal(env, funcArg[ArgumentPosition::SECOND]);
798     tie(succ, windowBits) = windowBitsNVal.ToInt64();
799     if (!succ || windowBits < MIN_WINDOWBITS || windowBits > MAX_WINDOWBITS) {
800         NapiBusinessError().ThrowErr(env, EINVAL);
801         return {false, 0, nullptr, 0};
802     }
803 
804     NapiValue bufNVal(env, funcArg[ArgumentPosition::THIRD]);
805     void *buf = nullptr;
806     size_t bufLen = 0;
807     tie(succ, buf, bufLen) = bufNVal.ToArrayBuffer();
808     if (!succ) {
809         NapiBusinessError().ThrowErr(env, EINVAL);
810         return {false, 0, nullptr, 0};
811     }
812 
813     return {true, windowBits, buf, bufLen};
814 }
815 
GetInflatePrimeArg(napi_env env,const NapiFuncArg & funcArg)816 std::tuple<bool, int32_t, int32_t> CommonFunc::GetInflatePrimeArg(napi_env env, const NapiFuncArg &funcArg)
817 {
818     bool succ = CommonFunc::SetZStreamValue(env, funcArg);
819     if (!succ) {
820         NapiBusinessError().ThrowErr(env, EINVAL);
821         return {false, 0, 0};
822     }
823 
824     NapiValue bitsNVal(env, funcArg[ArgumentPosition::SECOND]);
825     int32_t bits = 0;
826     tie(succ, bits) = bitsNVal.ToInt32();
827     if (!succ) {
828         NapiBusinessError().ThrowErr(env, EINVAL);
829         return {false, 0, 0};
830     }
831 
832     // The third argument
833     NapiValue valueNVal(env, funcArg[ArgumentPosition::THIRD]);
834     int32_t value = 0;
835     tie(succ, value) = valueNVal.ToInt32();
836     if (!succ) {
837         NapiBusinessError().ThrowErr(env, EINVAL);
838         return {false, 0, 0};
839     }
840     return {true, bits, value};
841 }
842 
GetInflateValidateArg(napi_env env,const NapiFuncArg & funcArg)843 std::tuple<bool, int32_t> CommonFunc::GetInflateValidateArg(napi_env env, const NapiFuncArg &funcArg)
844 {
845     bool succ = CommonFunc::SetZStreamValue(env, funcArg);
846     if (!succ) {
847         NapiBusinessError().ThrowErr(env, EINVAL);
848         return {false, 0};
849     }
850 
851     NapiValue checkNVal(env, funcArg[ArgumentPosition::SECOND]);
852     int32_t check = 0;
853     tie(succ, check) = checkNVal.ToInt32();
854     if (!succ) {
855         NapiBusinessError().ThrowErr(env, EINVAL);
856         return {false, 0};
857     }
858 
859     return {true, check};
860 }
861 
GetInflateGetHeaderArg(napi_env env,const NapiFuncArg & funcArg)862 std::tuple<bool, gz_header> CommonFunc::GetInflateGetHeaderArg(napi_env env, const NapiFuncArg &funcArg)
863 {
864     bool succ = CommonFunc::SetZStreamValue(env, funcArg);
865     if (!succ) {
866         NapiBusinessError().ThrowErr(env, EINVAL);
867         return {false, {}};
868     }
869 
870     gz_header gzHeader = {};
871     tie(succ, gzHeader) = CommonFunc::GetGZHeaderArg(env, funcArg[ArgumentPosition::SECOND]);
872     if (!succ) {
873         return {false, {}};
874     }
875 
876     return {true, gzHeader};
877 }
878 
UnwrapInt32Params(napi_env env,napi_value value)879 std::tuple<bool, int32_t> CommonFunc::UnwrapInt32Params(napi_env env, napi_value value)
880 {
881     bool succ = false;
882 
883     // The first argument
884     NapiValue valueNVal(env, value);
885     int32_t valueInt = 0;
886     tie(succ, valueInt) = valueNVal.ToInt32();
887     if (!succ || valueInt < 0) {
888         NapiBusinessError().ThrowErr(env, EINVAL);
889         return {false, 0};
890     }
891 
892     return {true, valueInt};
893 }
894 
UnwrapInt64Params(napi_env env,const NapiFuncArg & funcArg)895 std::tuple<bool, uint32_t> CommonFunc::UnwrapInt64Params(napi_env env, const NapiFuncArg &funcArg)
896 {
897     bool succ = CommonFunc::SetZStreamValue(env, funcArg);
898     if (!succ) {
899         NapiBusinessError().ThrowErr(env, EINVAL);
900         return {false, {}};
901     }
902 
903     // The first argument
904     NapiValue valueNVal(env, funcArg[ArgumentPosition::SECOND]);
905     int64_t valueInt = 0;
906     tie(succ, valueInt) = valueNVal.ToInt64();
907     if (!succ || valueInt < 0) {
908         NapiBusinessError().ThrowErr(env, EINVAL);
909         return {false, 0};
910     }
911 
912     return {true, valueInt};
913 }
914 
UnwrapDeflateTuneParams(napi_env env,const NapiFuncArg & funcArg)915 std::tuple<bool, int32_t, int32_t, int32_t, int32_t> CommonFunc::UnwrapDeflateTuneParams(
916     napi_env env, const NapiFuncArg &funcArg)
917 {
918     bool succ = CommonFunc::SetZStreamValue(env, funcArg);
919     if (!succ) {
920         return {false, 0, 0, 0, 0};
921     }
922 
923     // The first argument
924     NapiValue goodLengthNVal(env, funcArg[ArgumentPosition::SECOND]);
925     int32_t goodLength = 0;
926     tie(succ, goodLength) = goodLengthNVal.ToInt32();
927     if (!succ) {
928         NapiBusinessError().ThrowErr(env, EINVAL);
929         return {false, 0, 0, 0, 0};
930     }
931 
932     NapiValue maxLazyNVal(env, funcArg[ArgumentPosition::THIRD]);
933     int32_t maxLazy = 0;
934     tie(succ, maxLazy) = maxLazyNVal.ToInt32();
935     if (!succ) {
936         NapiBusinessError().ThrowErr(env, EINVAL);
937         return {false, 0, 0, 0, 0};
938     }
939 
940     NapiValue niceLengthNVal(env, funcArg[ArgumentPosition::FOURTH]);
941     int32_t niceLength = 0;
942     tie(succ, niceLength) = niceLengthNVal.ToInt32();
943     if (!succ) {
944         NapiBusinessError().ThrowErr(env, EINVAL);
945         return {false, 0, 0, 0, 0};
946     }
947 
948     NapiValue maxChainNVal(env, funcArg[ArgumentPosition::FIFTH]);
949     int32_t maxChain = 0;
950     tie(succ, maxChain) = maxChainNVal.ToInt32();
951     if (!succ) {
952         NapiBusinessError().ThrowErr(env, EINVAL);
953         return {false, 0, 0, 0, 0};
954     }
955 
956     return {true, maxLazy, maxLazy, niceLength, maxChain};
957 }
958 
UnwrapArrayBufferParams(napi_env env,const NapiFuncArg & funcArg)959 std::tuple<bool, void *, size_t> CommonFunc::UnwrapArrayBufferParams(napi_env env, const NapiFuncArg &funcArg)
960 {
961     bool succ = CommonFunc::SetZStreamValue(env, funcArg);
962     if (!succ) {
963         return {false, nullptr, 0};
964     }
965 
966     NapiValue bufNVal(env, funcArg[ArgumentPosition::SECOND]);
967     void *buf = nullptr;
968     size_t bufLen = 0;
969     tie(succ, buf, bufLen) = bufNVal.ToArrayBuffer();
970     if (!succ) {
971         NapiBusinessError().ThrowErr(env, EINVAL);
972         return {false, nullptr, 0};
973     }
974 
975     return {true, buf, bufLen};
976 }
977 
UnwrapTwoIntParams(napi_env env,const NapiFuncArg & funcArg)978 std::tuple<bool, int32_t, int32_t> CommonFunc::UnwrapTwoIntParams(napi_env env, const NapiFuncArg &funcArg)
979 {
980     bool succ = CommonFunc::SetZStreamValue(env, funcArg);
981     if (!succ) {
982         return {false, 0, 0};
983     }
984 
985     // The first argument
986     NapiValue firstNVal(env, funcArg[ArgumentPosition::SECOND]);
987     int32_t oneInt = 0;
988     tie(succ, oneInt) = firstNVal.ToInt32();
989     if (!succ) {
990         NapiBusinessError().ThrowErr(env, EINVAL);
991         return {false, 0, 0};
992     }
993 
994     // The second argument
995     NapiValue secondNVal(env, funcArg[ArgumentPosition::THIRD]);
996     int32_t twoInt = 0;
997     tie(succ, twoInt) = secondNVal.ToInt32();
998     if (!succ) {
999         NapiBusinessError().ThrowErr(env, EINVAL);
1000         return {false, 0, 0};
1001     }
1002 
1003     return {true, oneInt, twoInt};
1004 }
1005 
GzipUnwrapArrayBufferParams(napi_env env,const NapiFuncArg & funcArg)1006 std::tuple<bool, void *, size_t> CommonFunc::GzipUnwrapArrayBufferParams(napi_env env, const NapiFuncArg &funcArg)
1007 {
1008     bool succ = false;
1009     void *buf = nullptr;
1010     size_t bufLen = 0;
1011     NapiValue bufNVal(env, funcArg[ArgumentPosition::FIRST]);
1012     tie(succ, buf, bufLen) = bufNVal.ToArrayBuffer();
1013     if (!succ) {
1014         NapiBusinessError().ThrowErr(env, EINVAL);
1015         return {false, nullptr, 0};
1016     }
1017 
1018     return {true, buf, bufLen};
1019 }
1020 
GetGZOpenArg(napi_env env,const NapiFuncArg & funcArg)1021 std::tuple<bool, std::unique_ptr<char[]>, std::unique_ptr<char[]>> CommonFunc::GetGZOpenArg(
1022     napi_env env, const NapiFuncArg &funcArg)
1023 {
1024     bool succ = false;
1025     std::unique_ptr<char[]> path = nullptr;
1026     size_t bufferLen = 0;
1027     NapiValue pathNVal(env, funcArg[ArgumentPosition::FIRST]);
1028     tie(succ, path, bufferLen) = pathNVal.ToUTF8String();
1029     if (!succ) {
1030         NapiBusinessError().ThrowErr(env, EINVAL);
1031         return {false, nullptr, nullptr};
1032     }
1033 
1034     std::unique_ptr<char[]> mode = nullptr;
1035     bufferLen = 0;
1036     NapiValue modeNVal(env, funcArg[ArgumentPosition::SECOND]);
1037     tie(succ, mode, bufferLen) = modeNVal.ToUTF8String();
1038     if (!succ) {
1039         NapiBusinessError().ThrowErr(env, EINVAL);
1040         return {false, nullptr, nullptr};
1041     }
1042     return {true, std::move(path), std::move(mode)};
1043 }
1044 
GetGZDOpenArg(napi_env env,const NapiFuncArg & funcArg)1045 std::tuple<bool, int32_t, std::unique_ptr<char[]>> CommonFunc::GetGZDOpenArg(napi_env env, const NapiFuncArg &funcArg)
1046 {
1047     bool succ = false;
1048     int32_t fd = -1;
1049     NapiValue fdNVal(env, funcArg[ArgumentPosition::FIRST]);
1050     tie(succ, fd) = fdNVal.ToInt32();
1051     if (!succ) {
1052         NapiBusinessError().ThrowErr(env, EINVAL);
1053         return {false, -1, nullptr};
1054     }
1055 
1056     std::unique_ptr<char[]> mode = nullptr;
1057     size_t bufferLen = 0;
1058     NapiValue modeNVal(env, funcArg[ArgumentPosition::SECOND]);
1059     tie(succ, mode, bufferLen) = modeNVal.ToUTF8String();
1060     if (!succ) {
1061         NapiBusinessError().ThrowErr(env, EINVAL);
1062         return {false, -1, nullptr};
1063     }
1064     return {true, fd, std::move(mode)};
1065 }
1066 
GetGZFileArg(napi_env env,napi_value argGZFile)1067 std::tuple<bool, gzFile_s, HasGZFileMember> CommonFunc::GetGZFileArg(napi_env env, napi_value argGZFile)
1068 {
1069     gzFile_s gzs = {};
1070     bool succ = false;
1071     NapiValue gzFileNVal(env, argGZFile);
1072     HasGZFileMember hasGZFileMember = {};
1073 
1074     if (gzFileNVal.HasProp("have") && !gzFileNVal.GetProp("have").TypeIs(napi_undefined)) {
1075         uint32_t have = 0;
1076         tie(succ, have) = gzFileNVal.GetProp("have").ToUint32();
1077         if (!succ) {
1078             NapiBusinessError().ThrowErr(env, EINVAL);
1079             return {false, {}, {}};
1080         }
1081         gzs.have = have;
1082         hasGZFileMember.hasHave = true;
1083     }
1084 
1085     if (gzFileNVal.HasProp("next") && !gzFileNVal.GetProp("next").TypeIs(napi_undefined)) {
1086         void *buf = nullptr;
1087         size_t bufLen = 0;
1088         tie(succ, buf, bufLen) = gzFileNVal.GetProp("next").ToArrayBuffer();
1089         if (!succ) {
1090             NapiBusinessError().ThrowErr(env, EINVAL);
1091             return {false, {}, {}};
1092         }
1093         gzs.next = reinterpret_cast<Bytef *>(buf);
1094         hasGZFileMember.hasNext = true;
1095     }
1096 
1097     if (gzFileNVal.HasProp("pos") && !gzFileNVal.GetProp("pos").TypeIs(napi_undefined)) {
1098         uint64_t pos = 0U;
1099         tie(succ, pos) = gzFileNVal.GetProp("pos").ToInt64();
1100         if (!succ) {
1101             NapiBusinessError().ThrowErr(env, EINVAL);
1102             return {false, {}, {}};
1103         }
1104         gzs.pos = static_cast<z_off64_t>(pos);
1105         hasGZFileMember.hasPos = true;
1106     }
1107     return {true, gzs, hasGZFileMember};
1108 }
1109 
GetGZBufferArg(napi_env env,const NapiFuncArg & funcArg)1110 std::tuple<bool, uint32_t> CommonFunc::GetGZBufferArg(napi_env env, const NapiFuncArg &funcArg)
1111 {
1112     bool succ = false;
1113     uint32_t size = 0;
1114     NapiValue sizeNVal(env, funcArg[ArgumentPosition::FIRST]);
1115     tie(succ, size) = sizeNVal.ToUint32();
1116     if (!succ) {
1117         NapiBusinessError().ThrowErr(env, EINVAL);
1118         return {false, 0};
1119     }
1120     return {true, size};
1121 }
1122 
GetGZReadArg(napi_env env,const NapiFuncArg & funcArg)1123 std::tuple<bool, void *, uint32_t> CommonFunc::GetGZReadArg(napi_env env, const NapiFuncArg &funcArg)
1124 {
1125     bool succ = false;
1126     void *buf = nullptr;
1127     size_t len = 0;
1128     tie(succ, buf, len) = GzipUnwrapArrayBufferParams(env, funcArg);
1129     if (!succ || len == 0) {
1130         NapiBusinessError().ThrowErr(env, EINVAL);
1131         return {false, nullptr, 0};
1132     }
1133     return {true, buf, len};
1134 }
1135 
GetGZFReadArg(napi_env env,const NapiFuncArg & funcArg)1136 std::tuple<bool, void *, int64_t, int64_t> CommonFunc::GetGZFReadArg(napi_env env, const NapiFuncArg &funcArg)
1137 {
1138     bool succ = false;
1139     void *buf = nullptr;
1140     size_t len = 0;
1141     tie(succ, buf, len) = GzipUnwrapArrayBufferParams(env, funcArg);
1142     if (!succ || len == 0) {
1143         NapiBusinessError().ThrowErr(env, EINVAL);
1144         return {false, nullptr, 0, 0};
1145     }
1146 
1147     int64_t size = 0;
1148     NapiValue sizeNVal(env, funcArg[ArgumentPosition::SECOND]);
1149     tie(succ, size) = sizeNVal.ToInt64();
1150     if (!succ || size < 0) {
1151         NapiBusinessError().ThrowErr(env, EINVAL);
1152         return {false, nullptr, 0, 0};
1153     }
1154 
1155     int64_t nitems = 0;
1156     NapiValue nitemsNVal(env, funcArg[ArgumentPosition::THIRD]);
1157     tie(succ, nitems) = nitemsNVal.ToInt64();
1158     if (!succ || nitems < 0) {
1159         NapiBusinessError().ThrowErr(env, EINVAL);
1160         return {false, nullptr, 0, 0};
1161     }
1162     return {true, buf, size, nitems};
1163 }
1164 
GetGZWriteArg(napi_env env,const NapiFuncArg & funcArg)1165 std::tuple<bool, void *, int64_t> CommonFunc::GetGZWriteArg(napi_env env, const NapiFuncArg &funcArg)
1166 {
1167     bool succ = false;
1168     void *buf = nullptr;
1169     size_t bufLen = 0;
1170     tie(succ, buf, bufLen) = GzipUnwrapArrayBufferParams(env, funcArg);
1171     if (!succ || bufLen == 0) {
1172         NapiBusinessError().ThrowErr(env, EINVAL);
1173         return {false, nullptr, 0};
1174     }
1175     int64_t len = 0;
1176     NapiValue sizeNVal(env, funcArg[ArgumentPosition::SECOND]);
1177     tie(succ, len) = sizeNVal.ToInt64();
1178     if (!succ) {
1179         NapiBusinessError().ThrowErr(env, EINVAL);
1180         return {false, nullptr, 0};
1181     }
1182     return {true, buf, len};
1183 }
1184 
GetGZFWriteArg(napi_env env,const NapiFuncArg & funcArg)1185 std::tuple<bool, void *, int64_t, int64_t> CommonFunc::GetGZFWriteArg(napi_env env, const NapiFuncArg &funcArg)
1186 {
1187     bool succ = false;
1188     void *buf = nullptr;
1189     size_t len = 0;
1190     tie(succ, buf, len) = GzipUnwrapArrayBufferParams(env, funcArg);
1191     if (!succ || len == 0) {
1192         NapiBusinessError().ThrowErr(env, EINVAL);
1193         return {false, nullptr, 0, 0};
1194     }
1195 
1196     int64_t size = 0;
1197     NapiValue sizeNVal(env, funcArg[ArgumentPosition::SECOND]);
1198     tie(succ, size) = sizeNVal.ToInt64();
1199     if (!succ || size < 0) {
1200         NapiBusinessError().ThrowErr(env, EINVAL);
1201         return {false, nullptr, 0, 0};
1202     }
1203 
1204     int64_t nitems = 0;
1205     NapiValue nitemsNVal(env, funcArg[ArgumentPosition::THIRD]);
1206     tie(succ, nitems) = nitemsNVal.ToInt64();
1207     if (!succ || nitems < 0) {
1208         NapiBusinessError().ThrowErr(env, EINVAL);
1209         return {false, nullptr, 0, 0};
1210     }
1211     return {true, buf, size, nitems};
1212 }
1213 
GetGZPutCArg(napi_env env,const NapiFuncArg & funcArg)1214 std::tuple<bool, int32_t> CommonFunc::GetGZPutCArg(napi_env env, const NapiFuncArg &funcArg)
1215 {
1216     bool succ = false;
1217     int32_t c = 0;
1218     NapiValue cNVal(env, funcArg[ArgumentPosition::FIRST]);
1219     tie(succ, c) = cNVal.ToInt32();
1220     if (!succ) {
1221         NapiBusinessError().ThrowErr(env, EINVAL);
1222         return {false, 0};
1223     }
1224     if (c < MIN_ASCII || c > MAX_ASCII) {
1225         NapiBusinessError().ThrowErr(env, EINVAL);
1226         return {false, 0};
1227     }
1228     return {true, c};
1229 }
1230 
GetGZPutSArg(napi_env env,const NapiFuncArg & funcArg)1231 std::tuple<bool, std::unique_ptr<char[]>> CommonFunc::GetGZPutSArg(napi_env env, const NapiFuncArg &funcArg)
1232 {
1233     bool succ = false;
1234     std::unique_ptr<char[]> s = nullptr;
1235     size_t len = 0;
1236     NapiValue sNVal(env, funcArg[ArgumentPosition::FIRST]);
1237     tie(succ, s, len) = sNVal.ToUTF8String();
1238     if (!succ) {
1239         NapiBusinessError().ThrowErr(env, EINVAL);
1240         return {false, nullptr};
1241     }
1242     return {true, std::move(s)};
1243 }
1244 
GetGzSetParamsArg(napi_env env,const NapiFuncArg & funcArg)1245 std::tuple<bool, int32_t, int32_t> CommonFunc::GetGzSetParamsArg(napi_env env, const NapiFuncArg &funcArg)
1246 {
1247     bool succ = false;
1248     int32_t level = 0;
1249     NapiValue levelNapiValue(env, funcArg[ArgumentPosition::FIRST]);
1250     tie(succ, level) = levelNapiValue.ToInt32();
1251     if (!succ) {
1252         NapiBusinessError().ThrowErr(env, EINVAL);
1253         return {false, -1, -1};
1254     }
1255 
1256     int32_t strategy = 0;
1257     NapiValue strategyNapiValue(env, funcArg[ArgumentPosition::SECOND]);
1258     tie(succ, strategy) = strategyNapiValue.ToInt32();
1259     if (!succ) {
1260         NapiBusinessError().ThrowErr(env, EINVAL);
1261         return {false, -1, -1};
1262     }
1263     return {true, level, strategy};
1264 }
1265 
GetLogContent(string & formatStr,const vector<NapiParam> & params,string & ret,uint32_t & pos)1266 void CommonFunc::GetLogContent(string &formatStr, const vector<NapiParam> &params, string &ret, uint32_t &pos)
1267 {
1268     uint32_t count = 0;
1269     for (; pos < formatStr.size(); ++pos) {
1270         if (count >= params.size()) {
1271             break;
1272         }
1273         if (formatStr[pos] != '%') {
1274             ret += formatStr[pos];
1275             continue;
1276         }
1277         if (pos + 1 >= formatStr.size()) {
1278             break;
1279         }
1280         switch (formatStr[pos + 1]) {
1281             case 'd':
1282             case 'i':
1283                 if (params[count].type == napi_number || params[count].type == napi_bigint) {
1284                     ret += params[count].val;
1285                 }
1286                 count++;
1287                 ++pos;
1288                 break;
1289             case 's':
1290                 if (params[count].type == napi_string || params[count].type == napi_undefined ||
1291                     params[count].type == napi_boolean || params[count].type == napi_null) {
1292                     ret += params[count].val;
1293                 }
1294                 count++;
1295                 ++pos;
1296                 break;
1297             case 'O':
1298             case 'o':
1299                 if (params[count].type == napi_object) {
1300                     ret += params[count].val;
1301                 }
1302                 count++;
1303                 ++pos;
1304                 break;
1305             case '%':
1306                 ret += formatStr[pos];
1307                 ++pos;
1308                 break;
1309             default:
1310                 ret += formatStr[pos];
1311                 break;
1312         }
1313     }
1314     return;
1315 }
1316 
ParseLogContent(string & formatStr,vector<NapiParam> & params,string & logContent)1317 void CommonFunc::ParseLogContent(string &formatStr, vector<NapiParam> &params, string &logContent)
1318 {
1319     std::string &ret = logContent;
1320     if (params.empty()) {
1321         ret += formatStr;
1322         return;
1323     }
1324     auto len = formatStr.size();
1325     uint32_t pos = 0;
1326     GetLogContent(formatStr, params, ret, pos);
1327     if (pos < len) {
1328         ret += formatStr.substr(pos, len - pos);
1329     }
1330     return;
1331 }
1332 
ParseNapiValue(napi_env env,napi_value element,vector<NapiParam> & params)1333 void CommonFunc::ParseNapiValue(napi_env env, napi_value element, vector<NapiParam> &params)
1334 {
1335     bool succ = false;
1336     napi_valuetype type;
1337     NapiParam res = {napi_null, ""};
1338     napi_status typeStatus = napi_typeof(env, element, &type);
1339     unique_ptr<char[]> name;
1340     size_t len = 0;
1341     if (typeStatus != napi_ok) {
1342         NapiBusinessError().ThrowErr(env, EINVAL);
1343         return;
1344     }
1345     if (type == napi_number || type == napi_bigint || type == napi_object || type == napi_undefined ||
1346         type == napi_boolean || type == napi_null) {
1347         napi_value elmString;
1348         napi_status objectStatus = napi_coerce_to_string(env, element, &elmString);
1349         if (objectStatus != napi_ok) {
1350             NapiBusinessError().ThrowErr(env, EINVAL);
1351             return;
1352         }
1353         NapiValue elmNVal(env, elmString);
1354         tie(succ, name, len) = elmNVal.ToUTF8String();
1355         if (!succ) {
1356             NapiBusinessError().ThrowErr(env, EINVAL);
1357             return;
1358         }
1359     } else if (type == napi_string) {
1360         NapiValue elmNVal(env, element);
1361         tie(succ, name, len) = elmNVal.ToUTF8String();
1362         if (!succ) {
1363             NapiBusinessError().ThrowErr(env, EINVAL);
1364             return;
1365         }
1366     } else {
1367         NapiBusinessError().ThrowErr(env, EINVAL);
1368     }
1369     res.type = type;
1370     if (name != nullptr) {
1371         res.val = name.get();
1372     }
1373     params.emplace_back(res);
1374     return;
1375 }
1376 
ParseNapiValueFromArray(napi_env env,vector<NapiParam> & params,const NapiFuncArg & funcArg)1377 bool CommonFunc::ParseNapiValueFromArray(napi_env env, vector<NapiParam> &params, const NapiFuncArg &funcArg)
1378 {
1379     napi_value array = funcArg[ArgumentPosition::SECOND];
1380     if (funcArg.GetArgc() != MIN_NUMBER + 1) {
1381         NapiBusinessError().ThrowErr(env, EINVAL);
1382         return false;
1383     }
1384     uint32_t length;
1385     napi_status lengthStatus = napi_get_array_length(env, array, &length);
1386     if (lengthStatus != napi_ok) {
1387         return false;
1388     }
1389     uint32_t i;
1390     for (i = 0; i < length; i++) {
1391         napi_value element;
1392         napi_status eleStatus = napi_get_element(env, array, i, &element);
1393         if (eleStatus != napi_ok) {
1394             return false;
1395         }
1396         ParseNapiValue(env, element, params);
1397     }
1398     return true;
1399 }
1400 
GetGZPrintFArg(napi_env env,const NapiFuncArg & funcArg)1401 std::tuple<bool, std::unique_ptr<char[]>, std::unique_ptr<char[]>> CommonFunc::GetGZPrintFArg(
1402     napi_env env, const NapiFuncArg &funcArg)
1403 {
1404     bool succ = false;
1405     std::unique_ptr<char[]> fmtChar = nullptr;
1406     size_t len = 0;
1407     NapiValue formatNapiValue(env, funcArg[ArgumentPosition::FIRST]);
1408     tie(succ, fmtChar, len) = formatNapiValue.ToUTF8String();
1409     if (!succ) {
1410         NapiBusinessError().ThrowErr(env, EINVAL);
1411         return {false, nullptr, nullptr};
1412     }
1413     std::string fmtString = fmtChar.get();
1414 
1415     bool res = false;
1416     napi_value array = funcArg[ArgumentPosition::SECOND];
1417     napi_is_array(env, array, &res);
1418     std::string printContent;
1419     vector<NapiParam> params;
1420     if (!res) {
1421         for (size_t i = MIN_NUMBER; i < funcArg.GetArgc(); i++) {
1422             napi_value argsVal = funcArg[i];
1423             ParseNapiValue(env, argsVal, params);
1424         }
1425     } else {
1426         bool isSuccess = ParseNapiValueFromArray(env, params, funcArg);
1427         if (!isSuccess) {
1428             return {false, nullptr, nullptr};
1429         }
1430     }
1431     ParseLogContent(fmtString, params, printContent);
1432 
1433     std::unique_ptr<char[]> formatChar = nullptr;
1434     NapiValue formatNVal = NapiValue::CreateUTF8String(env, "%s");
1435     tie(succ, formatChar, len) = formatNVal.ToUTF8String();
1436     std::unique_ptr<char[]> argsChar = nullptr;
1437     NapiValue printNVal = NapiValue::CreateUTF8String(env, printContent);
1438     tie(succ, argsChar, len) = printNVal.ToUTF8String();
1439     return {true, std::move(formatChar), std::move(argsChar)};
1440 }
1441 
GetGZGetSArg(napi_env env,const NapiFuncArg & funcArg)1442 std::tuple<bool, void *, size_t> CommonFunc::GetGZGetSArg(napi_env env, const NapiFuncArg &funcArg)
1443 {
1444     bool succ = false;
1445     void *buffer = nullptr;
1446     size_t bufferLen = 0;
1447     NapiValue bufferNVal(env, funcArg[ArgumentPosition::FIRST]);
1448     tie(succ, buffer, bufferLen) = bufferNVal.ToArrayBuffer();
1449     if (!succ) {
1450         NapiBusinessError().ThrowErr(env, EINVAL);
1451         return {false, nullptr, 0};
1452     }
1453     return {true, buffer, bufferLen};
1454 }
1455 
GetGZSeekArg(napi_env env,const NapiFuncArg & funcArg)1456 std::tuple<bool, int64_t, int32_t> CommonFunc::GetGZSeekArg(napi_env env, const NapiFuncArg &funcArg)
1457 {
1458     bool succ = false;
1459     int64_t offset = 0;
1460     NapiValue offsetNVal(env, funcArg[ArgumentPosition::FIRST]);
1461     tie(succ, offset) = offsetNVal.ToInt64();
1462     if (!succ) {
1463         NapiBusinessError().ThrowErr(env, EINVAL);
1464         return {false, 0, 0};
1465     }
1466 
1467     int32_t whence = 0;
1468     NapiValue whenceNVal(env, funcArg[ArgumentPosition::SECOND]);
1469     tie(succ, whence) = whenceNVal.ToInt32();
1470     if (!succ) {
1471         NapiBusinessError().ThrowErr(env, EINVAL);
1472         return {false, 0, 0};
1473     }
1474     return {true, offset, whence};
1475 }
1476 
GetGZUnGetCArg(napi_env env,const NapiFuncArg & funcArg)1477 std::tuple<bool, int32_t> CommonFunc::GetGZUnGetCArg(napi_env env, const NapiFuncArg &funcArg)
1478 {
1479     bool succ = false;
1480     int32_t c = 0;
1481     NapiValue cNVal(env, funcArg[ArgumentPosition::FIRST]);
1482     tie(succ, c) = cNVal.ToInt32();
1483     if (!succ) {
1484         NapiBusinessError().ThrowErr(env, EINVAL);
1485         return {false, 0};
1486     }
1487     if (c < MIN_ASCII || c > MAX_ASCII) {
1488         NapiBusinessError().ThrowErr(env, EINVAL);
1489         return {false, 0};
1490     }
1491     return {true, c};
1492 }
1493 
SetGZFlushArg(napi_env env,const NapiFuncArg & funcArg)1494 std::tuple<bool, uint32_t> CommonFunc::SetGZFlushArg(napi_env env, const NapiFuncArg &funcArg)
1495 {
1496     bool succ = false;
1497     uint32_t flush = 0;
1498     NapiValue sizeNVal(env, funcArg[ArgumentPosition::FIRST]);
1499     tie(succ, flush) = sizeNVal.ToUint32();
1500     if (!succ) {
1501         NapiBusinessError().ThrowErr(env, EINVAL);
1502         return {false, 0};
1503     }
1504     return {true, flush};
1505 }
1506 
1507 }  // namespace LIBZIP
1508 }  // namespace AppExecFwk
1509 }  // namespace OHOS