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