• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2024 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  * http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #include "gzip_n_exporter.h"
17 
18 #include <cstdio>
19 #include <cstdlib>
20 #include <cstring>
21 #include <functional>
22 #include <memory>
23 #include <sstream>
24 #include <string>
25 #include <tuple>
26 
27 #include "common/common_func.h"
28 #include "common/napi_async_work_callback.h"
29 #include "common/napi_async_work_promise.h"
30 #include "common/napi_class.h"
31 #include "common/napi_func_arg.h"
32 #include "common/napi_business_error.h"
33 #include "gzip_entity.h"
34 #include "zlib.h"
35 
36 namespace OHOS {
37 namespace AppExecFwk {
38 namespace LIBZIP {
39 
40 static constexpr int MIN_NUMBER = 1;
41 static constexpr int MAX_NUMBER = 101;
42 
43 struct AsyncGZipArg {
44     std::unique_ptr<char[]> path = nullptr;
45     std::unique_ptr<char[]> mode = nullptr;
46     int32_t fd = -1;
47     int32_t errCode = 0;
48     int32_t flushMode = 0;
49     const char *errMsg = nullptr;
50 
51     // write fwrite read fread gets
52     void *buf = nullptr;
53     int64_t bufLen = 0;
54     int64_t size = 0;
55     int64_t nitems = 0;
56     int64_t readLen = 0;
57     int64_t writeLen = 0;
58     char *nullTerminatedString = nullptr;
59     // putc puts
60     int32_t c = 0;
61     std::unique_ptr<char[]> s = nullptr;
62     int32_t putLen = 0;
63     // tell tell64 seek seek64 offset offset64
64     int64_t seekOffset = 0;
65     int32_t seekWhence = 0;
66     int32_t offset = 0;
67     int64_t offset64 = 0;
68     // setparam
69     int32_t level = 0;
70     int32_t strategy = 0;
71     // printf
72     std::string printContent = "";
73     int32_t printResult = 0;
74     std::unique_ptr<char[]> format = nullptr;
75     std::unique_ptr<char[]> args = nullptr;
76     // ungetc
77     int32_t character = -1;
78 
79     AsyncGZipArg() = default;
80     ~AsyncGZipArg() = default;
81 };
82 
Constructor(napi_env env,napi_callback_info info)83 napi_value GZipNExporter::Constructor(napi_env env, napi_callback_info info)
84 {
85     NapiFuncArg funcArg(env, info);
86     if (!funcArg.InitArgs(ArgumentCount::ZERO)) {
87         NapiBusinessError().ThrowErr(env, EINVAL);
88         return nullptr;
89     }
90 
91     std::unique_ptr<GZipEntity> gzipEntity = std::make_unique<GZipEntity>();
92     if (!NapiClass::SetEntityFor<GZipEntity>(env, funcArg.GetThisVar(), move(gzipEntity))) {
93         NapiBusinessError(EIO).ThrowErr(env, "Failed to wrap entity for obj gzip");
94         return nullptr;
95     }
96     return funcArg.GetThisVar();
97 }
98 
Export()99 bool GZipNExporter::Export()
100 {
101     std::vector<napi_property_descriptor> props = {
102         NapiValue::DeclareNapiFunction("gzdopen", GZDopen),
103         NapiValue::DeclareNapiFunction("gzopen", GZOpen),
104         NapiValue::DeclareNapiFunction("gzclose", GZClose),
105         NapiValue::DeclareNapiFunction("gzclosew", GZCloseW),
106         NapiValue::DeclareNapiFunction("gzbuffer", GZBuffer),
107         NapiValue::DeclareNapiFunction("gzread", GZRead),
108         NapiValue::DeclareNapiFunction("gzfread", GZFRead),
109         NapiValue::DeclareNapiFunction("gzwrite", GZWrite),
110         NapiValue::DeclareNapiFunction("gzfwrite", GZFWrite),
111         NapiValue::DeclareNapiFunction("gzputc", GZPutC),
112         NapiValue::DeclareNapiFunction("gzputs", GZPutS),
113         NapiValue::DeclareNapiFunction("gztell", GZTell),
114         NapiValue::DeclareNapiFunction("gzsetparams", GZSetParams),
115         NapiValue::DeclareNapiFunction("gzprintf", GZPrintF),
116         NapiValue::DeclareNapiFunction("gzcloser", GZCloseR),
117         NapiValue::DeclareNapiFunction("gzgets", GZGetS),
118         NapiValue::DeclareNapiFunction("gzgetc", GZGetC),
119         NapiValue::DeclareNapiFunction("gzrewind", GZRewind),
120         NapiValue::DeclareNapiFunction("gzseek", GZSeek),
121         NapiValue::DeclareNapiFunction("gzoffset", GZOffset),
122         NapiValue::DeclareNapiFunction("gzungetc", GZUnGetC),
123         NapiValue::DeclareNapiFunction("gzclearerr", GZClearerr),
124         NapiValue::DeclareNapiFunction("gzdirect", GZDirect),
125         NapiValue::DeclareNapiFunction("gzeof", GZeof),
126         NapiValue::DeclareNapiFunction("gzerror", GZError),
127         NapiValue::DeclareNapiFunction("gzflush", GZFlush),
128     };
129 
130     std::string className = GetClassName();
131     bool succ = false;
132     napi_value cls = nullptr;
133     std::tie(succ, cls) = NapiClass::DefineClass(exports_.env_, className, GZipNExporter::Constructor, move(props));
134     if (!succ) {
135         NapiBusinessError().ThrowErr(exports_.env_, "Failed to define class");
136         return false;
137     }
138     succ = NapiClass::SaveClass(exports_.env_, className, cls);
139     if (!succ) {
140         NapiBusinessError().ThrowErr(exports_.env_, "Failed to save class");
141         return false;
142     }
143 
144     return exports_.AddProp(className, cls);
145 }
146 
GetClassName()147 std::string GZipNExporter::GetClassName()
148 {
149     return GZipNExporter::className_;
150 }
151 
GZipNExporter(napi_env env,napi_value exports)152 GZipNExporter::GZipNExporter(napi_env env, napi_value exports) : NapiExporter(env, exports)
153 {}
154 
~GZipNExporter()155 GZipNExporter::~GZipNExporter()
156 {}
157 
GZDopen(napi_env env,napi_callback_info info)158 napi_value GZipNExporter::GZDopen(napi_env env, napi_callback_info info)
159 {
160     NapiFuncArg funcArg(env, info);
161     if (!funcArg.InitArgs(ArgumentCount::TWO, ArgumentCount::THREE)) {
162         NapiBusinessError().ThrowErr(env, EINVAL);
163         return nullptr;
164     }
165 
166     auto arg = std::make_shared<AsyncGZipArg>();
167     /* To get entity */
168     auto gzipEntity = NapiClass::GetEntityOf<GZipEntity>(env, funcArg.GetThisVar());
169     if (!gzipEntity) {
170         NapiBusinessError().ThrowErr(env, EFAULT);
171         return nullptr;
172     }
173 
174     bool succ = false;
175     std::tie(succ, arg->fd, arg->mode) = CommonFunc::GetGZDOpenArg(env, funcArg);
176     if (!succ) {
177         return nullptr;
178     }
179     auto cbExec = [arg, gzipEntity](napi_env env) -> NapiBusinessError {
180         if (!gzipEntity) {
181             return NapiBusinessError(EFAULT, true);
182         }
183         auto file = gzdopen(arg->fd, arg->mode.get());
184         if (!file) {
185             return NapiBusinessError(ENOENT, true);
186         }
187         std::unique_ptr<gzFile_s, Deleter<gzFile_s>> gzFile(file);
188         gzipEntity->gzs.swap(gzFile);
189         return NapiBusinessError(ERRNO_NOERR);
190     };
191 
192     auto cbCompl = [](napi_env env, NapiBusinessError err) -> NapiValue {
193         if (err) {
194             return {env, err.GetNapiErr(env)};
195         }
196         return {NapiValue::CreateUndefined(env)};
197     };
198 
199     NapiValue thisVar(env, funcArg.GetThisVar());
200     if (funcArg.GetArgc() == ArgumentCount::TWO) {
201         return NapiAsyncWorkPromise(env, thisVar).Schedule(PROCEDURE_GZIP_NAME, cbExec, cbCompl).val_;
202     }
203 
204     return NapiValue::CreateUndefined(env).val_;
205 }
206 
GZOpen(napi_env env,napi_callback_info info)207 napi_value GZipNExporter::GZOpen(napi_env env, napi_callback_info info)
208 {
209     NapiFuncArg funcArg(env, info);
210     if (!funcArg.InitArgs(ArgumentCount::TWO, ArgumentCount::THREE)) {
211         NapiBusinessError().ThrowErr(env, EINVAL);
212         return nullptr;
213     }
214 
215     auto arg = std::make_shared<AsyncGZipArg>();
216     /* To get entity */
217     auto gzipEntity = NapiClass::GetEntityOf<GZipEntity>(env, funcArg.GetThisVar());
218     if (!gzipEntity) {
219         NapiBusinessError().ThrowErr(env, EFAULT);
220         return nullptr;
221     }
222 
223     bool succ = false;
224     std::tie(succ, arg->path, arg->mode) = CommonFunc::GetGZOpenArg(env, funcArg);
225     if (!succ) {
226         return nullptr;
227     }
228     auto cbExec = [arg, gzipEntity](napi_env env) -> NapiBusinessError {
229         if (!gzipEntity) {
230             return NapiBusinessError(EFAULT, true);
231         }
232         gzFile file;
233 #if !defined(ZLIB_INTERNAL) && defined(Z_WANT64) && !defined(Z_LARGE64)
234         file = gzopen64(arg->path.get(), arg->mode.get());
235 #else
236         file = gzopen(arg->path.get(), arg->mode.get());
237 #endif
238         if (!file) {
239             return NapiBusinessError(ENOENT, true);
240         }
241         std::unique_ptr<gzFile_s, Deleter<gzFile_s>> gzFile(file);
242         gzipEntity->gzs.swap(gzFile);
243         return NapiBusinessError(ERRNO_NOERR);
244     };
245 
246     auto cbCompl = [](napi_env env, NapiBusinessError err) -> NapiValue {
247         if (err) {
248             return {env, err.GetNapiErr(env)};
249         }
250         return {NapiValue::CreateUndefined(env)};
251     };
252 
253     NapiValue thisVar(env, funcArg.GetThisVar());
254     if (funcArg.GetArgc() == ArgumentCount::TWO) {
255         return NapiAsyncWorkPromise(env, thisVar).Schedule(PROCEDURE_GZIP_NAME, cbExec, cbCompl).val_;
256     }
257 
258     return NapiValue::CreateUndefined(env).val_;
259 }
260 
GZCloseW(napi_env env,napi_callback_info info)261 napi_value GZipNExporter::GZCloseW(napi_env env, napi_callback_info info)
262 {
263     NapiFuncArg funcArg(env, info);
264     if (!funcArg.InitArgs(ArgumentCount::ZERO, ArgumentCount::ONE)) {
265         NapiBusinessError().ThrowErr(env, EINVAL);
266         return nullptr;
267     }
268 
269     auto arg = std::make_shared<AsyncGZipArg>();
270     /* To get entity */
271     auto gzipEntity = NapiClass::GetEntityOf<GZipEntity>(env, funcArg.GetThisVar());
272     if (!gzipEntity) {
273         NapiBusinessError().ThrowErr(env, EFAULT);
274         return nullptr;
275     }
276 
277     auto cbExec = [arg, gzipEntity](napi_env env) -> NapiBusinessError {
278         if (!gzipEntity) {
279             return NapiBusinessError(EFAULT, true);
280         }
281         arg->errCode = gzclose_w(gzipEntity->gzs.get());
282         if (arg->errCode < 0) {
283             return NapiBusinessError(arg->errCode, true);
284         }
285         return NapiBusinessError(ERRNO_NOERR);
286     };
287 
288     auto cbCompl = [arg](napi_env env, NapiBusinessError err) -> NapiValue {
289         if (err) {
290             return {env, err.GetNapiErr(env)};
291         } else if (!arg) {
292             return {NapiValue::CreateUndefined(env)};
293         }
294         return {NapiValue::CreateInt32(env, arg->errCode)};
295     };
296 
297     NapiValue thisVar(env, funcArg.GetThisVar());
298     if (funcArg.GetArgc() == ArgumentCount::ZERO) {
299         return NapiAsyncWorkPromise(env, thisVar).Schedule(PROCEDURE_GZIP_NAME, cbExec, cbCompl).val_;
300     }
301 
302     return NapiValue::CreateUndefined(env).val_;
303 }
304 
GZBuffer(napi_env env,napi_callback_info info)305 napi_value GZipNExporter::GZBuffer(napi_env env, napi_callback_info info)
306 {
307     NapiFuncArg funcArg(env, info);
308     if (!funcArg.InitArgs(ArgumentCount::ONE, ArgumentCount::TWO)) {
309         NapiBusinessError().ThrowErr(env, EINVAL);
310         return nullptr;
311     }
312 
313     auto arg = std::make_shared<AsyncGZipArg>();
314     /* To get entity */
315     auto gzipEntity = NapiClass::GetEntityOf<GZipEntity>(env, funcArg.GetThisVar());
316     if (!gzipEntity) {
317         NapiBusinessError().ThrowErr(env, EFAULT);
318         return nullptr;
319     }
320 
321     bool succ = false;
322     uint32_t size = 0;
323     std::tie(succ, size) = CommonFunc::GetGZBufferArg(env, funcArg);
324     if (!succ) {
325         return nullptr;
326     }
327     auto cbExec = [arg, gzipEntity, size](napi_env env) -> NapiBusinessError {
328         if (!gzipEntity) {
329             return NapiBusinessError(EFAULT, true);
330         }
331         arg->errCode = gzbuffer(gzipEntity->gzs.get(), size);
332         if (arg->errCode < 0) {
333             return NapiBusinessError(ENOSTR, true);
334         }
335         return NapiBusinessError(ERRNO_NOERR);
336     };
337 
338     auto cbCompl = [arg](napi_env env, NapiBusinessError err) -> NapiValue {
339         if (err) {
340             return {env, err.GetNapiErr(env)};
341         } else if (!arg) {
342             return {NapiValue::CreateUndefined(env)};
343         }
344         return {NapiValue::CreateInt32(env, arg->errCode)};
345     };
346 
347     NapiValue thisVar(env, funcArg.GetThisVar());
348     if (funcArg.GetArgc() == ArgumentCount::ONE) {
349         return NapiAsyncWorkPromise(env, thisVar).Schedule(PROCEDURE_GZIP_NAME, cbExec, cbCompl).val_;
350     }
351 
352     return NapiValue::CreateUndefined(env).val_;
353 }
354 
GZRead(napi_env env,napi_callback_info info)355 napi_value GZipNExporter::GZRead(napi_env env, napi_callback_info info)
356 {
357     NapiFuncArg funcArg(env, info);
358     if (!funcArg.InitArgs(ArgumentCount::ONE, ArgumentCount::TWO)) {
359         NapiBusinessError().ThrowErr(env, EINVAL);
360         return nullptr;
361     }
362 
363     auto arg = std::make_shared<AsyncGZipArg>();
364     /* To get entity */
365     auto gzipEntity = NapiClass::GetEntityOf<GZipEntity>(env, funcArg.GetThisVar());
366     if (!gzipEntity) {
367         NapiBusinessError().ThrowErr(env, EINVAL);
368         return nullptr;
369     }
370 
371     bool succ = false;
372     void *buffer = nullptr;
373     std::tie(succ, buffer, arg->bufLen) = CommonFunc::GetGZReadArg(env, funcArg);
374     if (!succ) {
375         return nullptr;
376     }
377 
378     auto cbExec = [arg, gzipEntity, buffer](napi_env env) -> NapiBusinessError {
379         if (!gzipEntity) {
380             return NapiBusinessError(EINVAL, true);
381         }
382         arg->readLen =
383             gzread(gzipEntity->gzs.get(), reinterpret_cast<void *>(buffer), static_cast<unsigned int>(arg->bufLen));
384         if (arg->readLen < 0) {
385             return NapiBusinessError(ENOSTR, true);
386         }
387         return NapiBusinessError(ERRNO_NOERR);
388     };
389 
390     auto cbCompl = [arg](napi_env env, NapiBusinessError err) -> NapiValue {
391         if (err) {
392             return {env, err.GetNapiErr(env)};
393         } else if (!arg) {
394             return {NapiValue::CreateUndefined(env)};
395         }
396         return {NapiValue::CreateInt64(env, arg->readLen)};
397     };
398 
399     NapiValue thisVar(env, funcArg.GetThisVar());
400     if (funcArg.GetArgc() == ArgumentCount::ONE) {
401         return NapiAsyncWorkPromise(env, thisVar).Schedule(PROCEDURE_GZIP_NAME, cbExec, cbCompl).val_;
402     }
403 
404     return NapiValue::CreateUndefined(env).val_;
405 }
406 
GZFRead(napi_env env,napi_callback_info info)407 napi_value GZipNExporter::GZFRead(napi_env env, napi_callback_info info)
408 {
409     NapiFuncArg funcArg(env, info);
410     if (!funcArg.InitArgs(ArgumentCount::THREE, ArgumentCount::FOUR)) {
411         NapiBusinessError().ThrowErr(env, EINVAL);
412         return nullptr;
413     }
414 
415     auto arg = std::make_shared<AsyncGZipArg>();
416     /* To get entity */
417     auto gzipEntity = NapiClass::GetEntityOf<GZipEntity>(env, funcArg.GetThisVar());
418     if (!gzipEntity) {
419         NapiBusinessError().ThrowErr(env, EINVAL);
420         return nullptr;
421     }
422 
423     bool succ = false;
424     void *buffer = nullptr;
425     std::tie(succ, buffer, arg->size, arg->nitems) = CommonFunc::GetGZFReadArg(env, funcArg);
426     if (!succ) {
427         return nullptr;
428     }
429 
430     auto cbExec = [arg, gzipEntity, buffer](napi_env env) -> NapiBusinessError {
431         if (!gzipEntity) {
432             return NapiBusinessError(EINVAL, true);
433         }
434         arg->readLen = static_cast<int64_t>(gzfread(reinterpret_cast<void *>(buffer),
435             static_cast<z_size_t>(arg->size), static_cast<z_size_t>(arg->nitems), gzipEntity->gzs.get()));
436         if (arg->readLen <= 0) {
437             return NapiBusinessError(ENOSTR, true);
438         }
439         return NapiBusinessError(ERRNO_NOERR);
440     };
441 
442     auto cbCompl = [arg](napi_env env, NapiBusinessError err) -> NapiValue {
443         if (err) {
444             return {env, err.GetNapiErr(env)};
445         } else if (!arg) {
446             return {NapiValue::CreateUndefined(env)};
447         }
448         return {NapiValue::CreateInt64(env, arg->readLen)};
449     };
450 
451     NapiValue thisVar(env, funcArg.GetThisVar());
452     if (funcArg.GetArgc() == ArgumentCount::THREE) {
453         return NapiAsyncWorkPromise(env, thisVar).Schedule(PROCEDURE_GZIP_NAME, cbExec, cbCompl).val_;
454     }
455 
456     return NapiValue::CreateUndefined(env).val_;
457 }
458 
GZWrite(napi_env env,napi_callback_info info)459 napi_value GZipNExporter::GZWrite(napi_env env, napi_callback_info info)
460 {
461     NapiFuncArg funcArg(env, info);
462     if (!funcArg.InitArgs(ArgumentCount::TWO, ArgumentCount::THREE)) {
463         NapiBusinessError().ThrowErr(env, EINVAL);
464         return nullptr;
465     }
466 
467     auto arg = std::make_shared<AsyncGZipArg>();
468     /* To get entity */
469     auto gzipEntity = NapiClass::GetEntityOf<GZipEntity>(env, funcArg.GetThisVar());
470     if (!gzipEntity) {
471         NapiBusinessError().ThrowErr(env, EINVAL);
472         return nullptr;
473     }
474 
475     bool succ = false;
476     std::tie(succ, arg->buf, arg->bufLen) = CommonFunc::GetGZWriteArg(env, funcArg);
477     if (!succ) {
478         return nullptr;
479     }
480 
481     auto cbExec = [arg, gzipEntity](napi_env env) -> NapiBusinessError {
482         if (!gzipEntity) {
483             return NapiBusinessError(EINVAL, true);
484         }
485         arg->writeLen = gzwrite(gzipEntity->gzs.get(), arg->buf, static_cast<unsigned int>(arg->bufLen));
486         if (arg->writeLen <= 0) {
487             return NapiBusinessError(ENOSTR, true);
488         }
489         return NapiBusinessError(ERRNO_NOERR);
490     };
491 
492     auto cbCompl = [arg](napi_env env, NapiBusinessError err) -> NapiValue {
493         if (err) {
494             return {env, err.GetNapiErr(env)};
495         } else if (!arg) {
496             return {NapiValue::CreateUndefined(env)};
497         }
498         return {NapiValue::CreateInt64(env, arg->writeLen)};
499     };
500 
501     NapiValue thisVar(env, funcArg.GetThisVar());
502     if (funcArg.GetArgc() == ArgumentCount::TWO) {
503         return NapiAsyncWorkPromise(env, thisVar).Schedule(PROCEDURE_GZIP_NAME, cbExec, cbCompl).val_;
504     }
505 
506     return NapiValue::CreateUndefined(env).val_;
507 }
508 
GZFWrite(napi_env env,napi_callback_info info)509 napi_value GZipNExporter::GZFWrite(napi_env env, napi_callback_info info)
510 {
511     NapiFuncArg funcArg(env, info);
512     if (!funcArg.InitArgs(ArgumentCount::THREE, ArgumentCount::FOUR)) {
513         NapiBusinessError().ThrowErr(env, EINVAL);
514         return nullptr;
515     }
516 
517     auto arg = std::make_shared<AsyncGZipArg>();
518     /* To get entity */
519     auto gzipEntity = NapiClass::GetEntityOf<GZipEntity>(env, funcArg.GetThisVar());
520     if (!gzipEntity) {
521         NapiBusinessError().ThrowErr(env, EINVAL);
522         return nullptr;
523     }
524 
525     bool succ = false;
526     std::tie(succ, arg->buf, arg->size, arg->nitems) = CommonFunc::GetGZFWriteArg(env, funcArg);
527     if (!succ) {
528         return nullptr;
529     }
530 
531     auto cbExec = [arg, gzipEntity](napi_env env) -> NapiBusinessError {
532         if (!gzipEntity) {
533             return NapiBusinessError(EINVAL, true);
534         }
535         arg->writeLen = static_cast<int64_t>(gzfwrite(
536             arg->buf, static_cast<z_size_t>(arg->size), static_cast<z_size_t>(arg->nitems), gzipEntity->gzs.get()));
537         if (arg->writeLen <= 0) {
538             return NapiBusinessError(ENOSTR, true);
539         }
540         return NapiBusinessError(ERRNO_NOERR);
541     };
542 
543     auto cbCompl = [arg](napi_env env, NapiBusinessError err) -> NapiValue {
544         if (err) {
545             return {env, err.GetNapiErr(env)};
546         } else if (!arg) {
547             return {NapiValue::CreateUndefined(env)};
548         }
549         return {NapiValue::CreateInt64(env, arg->writeLen)};
550     };
551 
552     NapiValue thisVar(env, funcArg.GetThisVar());
553     if (funcArg.GetArgc() == ArgumentCount::THREE) {
554         return NapiAsyncWorkPromise(env, thisVar).Schedule(PROCEDURE_GZIP_NAME, cbExec, cbCompl).val_;
555     }
556 
557     return NapiValue::CreateUndefined(env).val_;
558 }
559 
GZPutC(napi_env env,napi_callback_info info)560 napi_value GZipNExporter::GZPutC(napi_env env, napi_callback_info info)
561 {
562     NapiFuncArg funcArg(env, info);
563     if (!funcArg.InitArgs(ArgumentCount::ONE, ArgumentCount::TWO)) {
564         NapiBusinessError().ThrowErr(env, EINVAL);
565         return nullptr;
566     }
567 
568     auto arg = std::make_shared<AsyncGZipArg>();
569     /* To get entity */
570     auto gzipEntity = NapiClass::GetEntityOf<GZipEntity>(env, funcArg.GetThisVar());
571     if (!gzipEntity) {
572         NapiBusinessError().ThrowErr(env, EINVAL);
573         return nullptr;
574     }
575 
576     bool succ = false;
577     std::tie(succ, arg->c) = CommonFunc::GetGZPutCArg(env, funcArg);
578     if (!succ) {
579         return nullptr;
580     }
581 
582     auto cbExec = [arg, gzipEntity](napi_env env) -> NapiBusinessError {
583         if (!gzipEntity) {
584             return NapiBusinessError(EINVAL, true);
585         }
586         arg->c = gzputc(gzipEntity->gzs.get(), arg->c);
587         if (arg->c < 0) {
588             return NapiBusinessError(ENOSTR, true);
589         }
590         return NapiBusinessError(ERRNO_NOERR);
591     };
592 
593     auto cbCompl = [arg](napi_env env, NapiBusinessError err) -> NapiValue {
594         if (err) {
595             return {env, err.GetNapiErr(env)};
596         } else if (!arg) {
597             return {NapiValue::CreateUndefined(env)};
598         }
599         return {NapiValue::CreateInt32(env, arg->c)};
600     };
601 
602     NapiValue thisVar(env, funcArg.GetThisVar());
603     if (funcArg.GetArgc() == ArgumentCount::ONE) {
604         return NapiAsyncWorkPromise(env, thisVar).Schedule(PROCEDURE_GZIP_NAME, cbExec, cbCompl).val_;
605     }
606 
607     return NapiValue::CreateUndefined(env).val_;
608 }
609 
GZPutS(napi_env env,napi_callback_info info)610 napi_value GZipNExporter::GZPutS(napi_env env, napi_callback_info info)
611 {
612     NapiFuncArg funcArg(env, info);
613     if (!funcArg.InitArgs(ArgumentCount::ONE, ArgumentCount::TWO)) {
614         NapiBusinessError().ThrowErr(env, EINVAL);
615         return nullptr;
616     }
617 
618     auto arg = std::make_shared<AsyncGZipArg>();
619     /* To get entity */
620     auto gzipEntity = NapiClass::GetEntityOf<GZipEntity>(env, funcArg.GetThisVar());
621     if (!gzipEntity) {
622         NapiBusinessError().ThrowErr(env, EINVAL);
623         return nullptr;
624     }
625 
626     bool succ = false;
627     std::tie(succ, arg->s) = CommonFunc::GetGZPutSArg(env, funcArg);
628     if (!succ) {
629         return nullptr;
630     }
631 
632     auto cbExec = [arg, gzipEntity](napi_env env) -> NapiBusinessError {
633         if (!gzipEntity) {
634             return NapiBusinessError(EINVAL, true);
635         }
636         arg->putLen = gzputs(gzipEntity->gzs.get(), arg->s.get());
637         if (arg->putLen < 0) {
638             return NapiBusinessError(ENOSTR, true);
639         }
640         return NapiBusinessError(ERRNO_NOERR);
641     };
642 
643     auto cbCompl = [arg](napi_env env, NapiBusinessError err) -> NapiValue {
644         if (err) {
645             return {env, err.GetNapiErr(env)};
646         } else if (!arg) {
647             return {NapiValue::CreateUndefined(env)};
648         }
649         return {NapiValue::CreateInt32(env, arg->putLen)};
650     };
651 
652     NapiValue thisVar(env, funcArg.GetThisVar());
653     if (funcArg.GetArgc() == ArgumentCount::ONE) {
654         return NapiAsyncWorkPromise(env, thisVar).Schedule(PROCEDURE_GZIP_NAME, cbExec, cbCompl).val_;
655     }
656 
657     return NapiValue::CreateUndefined(env).val_;
658 }
659 
GZTell(napi_env env,napi_callback_info info)660 napi_value GZipNExporter::GZTell(napi_env env, napi_callback_info info)
661 {
662     NapiFuncArg funcArg(env, info);
663     if (!funcArg.InitArgs(ArgumentCount::ZERO, ArgumentCount::ONE)) {
664         NapiBusinessError().ThrowErr(env, EINVAL);
665         return nullptr;
666     }
667 
668     auto arg = std::make_shared<AsyncGZipArg>();
669     /* To get entity */
670     auto gzipEntity = NapiClass::GetEntityOf<GZipEntity>(env, funcArg.GetThisVar());
671     if (!gzipEntity) {
672         NapiBusinessError().ThrowErr(env, EINVAL);
673         return nullptr;
674     }
675 
676     auto cbExec = [arg, gzipEntity](napi_env env) -> NapiBusinessError {
677         if (!gzipEntity) {
678             return NapiBusinessError(EINVAL, true);
679         }
680 #if !defined(ZLIB_INTERNAL) && defined(Z_WANT64) && !defined(Z_LARGE64)
681         arg->offset64 = gztell64(gzipEntity->gzs.get());
682 #else
683         arg->offset = gztell(gzipEntity->gzs.get());
684 #endif
685         if (arg->offset < 0 || arg->offset64 < 0) {
686             return NapiBusinessError(ENOSTR, true);
687         }
688         return NapiBusinessError(ERRNO_NOERR);
689     };
690 
691     auto cbCompl = [arg](napi_env env, NapiBusinessError err) -> NapiValue {
692         if (err) {
693             return {env, err.GetNapiErr(env)};
694         } else if (!arg) {
695             return {NapiValue::CreateUndefined(env)};
696         }
697 #if !defined(ZLIB_INTERNAL) && defined(Z_WANT64) && !defined(Z_LARGE64)
698         return {NapiValue::CreateInt64(env, arg->offset64)};
699 #else
700         return {NapiValue::CreateInt32(env, arg->offset)};
701 #endif
702     };
703 
704     NapiValue thisVar(env, funcArg.GetThisVar());
705     if (funcArg.GetArgc() == ArgumentCount::ZERO) {
706         return NapiAsyncWorkPromise(env, thisVar).Schedule(PROCEDURE_GZIP_NAME, cbExec, cbCompl).val_;
707     }
708 
709     return NapiValue::CreateUndefined(env).val_;
710 }
711 
GZSetParams(napi_env env,napi_callback_info info)712 napi_value GZipNExporter::GZSetParams(napi_env env, napi_callback_info info)
713 {
714     NapiFuncArg funcArg(env, info);
715     if (!funcArg.InitArgs(ArgumentCount::TWO, ArgumentCount::THREE)) {
716         NapiBusinessError().ThrowErr(env, EINVAL);
717         return nullptr;
718     }
719 
720     auto arg = std::make_shared<AsyncGZipArg>();
721     /* To get entity */
722     auto gzipEntity = NapiClass::GetEntityOf<GZipEntity>(env, funcArg.GetThisVar());
723     if (!gzipEntity) {
724         NapiBusinessError().ThrowErr(env, EINVAL);
725         return nullptr;
726     }
727 
728     bool succ = false;
729     std::tie(succ, arg->level, arg->strategy) = CommonFunc::GetGzSetParamsArg(env, funcArg);
730     if (!succ) {
731         return nullptr;
732     }
733 
734     auto cbExec = [arg, gzipEntity](napi_env env) -> NapiBusinessError {
735         if (!gzipEntity) {
736             return NapiBusinessError(EINVAL, true);
737         }
738         arg->errCode = gzsetparams(gzipEntity->gzs.get(), arg->level, arg->strategy);
739         if (arg->errCode < 0) {
740             return NapiBusinessError(arg->errCode, true);
741         }
742         return NapiBusinessError(ERRNO_NOERR);
743     };
744 
745     auto cbCompl = [arg](napi_env env, NapiBusinessError err) -> NapiValue {
746         if (err) {
747             return {env, err.GetNapiErr(env)};
748         } else if (!arg) {
749             return {NapiValue::CreateUndefined(env)};
750         }
751         return {NapiValue::CreateInt32(env, arg->errCode)};
752     };
753 
754     NapiValue thisVar(env, funcArg.GetThisVar());
755     if (funcArg.GetArgc() == ArgumentCount::TWO) {
756         return NapiAsyncWorkPromise(env, thisVar).Schedule(PROCEDURE_GZIP_NAME, cbExec, cbCompl).val_;
757     }
758 
759     return NapiValue::CreateUndefined(env).val_;
760 }
761 
GZPrintF(napi_env env,napi_callback_info info)762 napi_value GZipNExporter::GZPrintF(napi_env env, napi_callback_info info)
763 {
764     NapiFuncArg funcArg(env, info);
765     if (!funcArg.InitArgs(MIN_NUMBER, MAX_NUMBER)) {
766         NapiBusinessError().ThrowErr(env, EINVAL);
767         return nullptr;
768     }
769 
770     auto arg = std::make_shared<AsyncGZipArg>();
771     /* To get entity */
772     auto gzipEntity = NapiClass::GetEntityOf<GZipEntity>(env, funcArg.GetThisVar());
773     if (!gzipEntity) {
774         NapiBusinessError().ThrowErr(env, EINVAL);
775         return nullptr;
776     }
777 
778     bool succ = false;
779     std::tie(succ, arg->format, arg->args) = CommonFunc::GetGZPrintFArg(env, funcArg);
780     if (!succ) {
781         return nullptr;
782     }
783 
784     auto cbExec = [arg, gzipEntity](napi_env env) -> NapiBusinessError {
785         if (!gzipEntity) {
786             return NapiBusinessError(EINVAL, true);
787         }
788         arg->printResult = gzprintf(gzipEntity->gzs.get(), arg->format.get(), arg->args.get());
789         if (arg->printResult <= 0) {
790             return NapiBusinessError(arg->printResult, true);
791         }
792         return NapiBusinessError(ERRNO_NOERR);
793     };
794 
795     auto cbCompl = [arg](napi_env env, NapiBusinessError err) -> NapiValue {
796         if (err) {
797             return {env, err.GetNapiErr(env)};
798         } else if (!arg) {
799             return {NapiValue::CreateUndefined(env)};
800         }
801         return {NapiValue::CreateInt32(env, arg->printResult)};
802     };
803 
804     NapiValue thisVar(env, funcArg.GetThisVar());
805     return NapiAsyncWorkPromise(env, thisVar).Schedule(PROCEDURE_GZIP_NAME, cbExec, cbCompl).val_;
806 }
807 
GZClose(napi_env env,napi_callback_info info)808 napi_value GZipNExporter::GZClose(napi_env env, napi_callback_info info)
809 {
810     NapiFuncArg funcArg(env, info);
811     if (!funcArg.InitArgs(ArgumentCount::ZERO, ArgumentCount::ONE)) {
812         NapiBusinessError().ThrowErr(env, EINVAL);
813         return nullptr;
814     }
815 
816     auto arg = std::make_shared<AsyncGZipArg>();
817     /* To get entity */
818     auto gzipEntity = NapiClass::GetEntityOf<GZipEntity>(env, funcArg.GetThisVar());
819     if (!gzipEntity) {
820         NapiBusinessError().ThrowErr(env, EINVAL);
821         return nullptr;
822     }
823 
824     auto cbExec = [arg, gzipEntity](napi_env env) -> NapiBusinessError {
825         if (!gzipEntity) {
826             return NapiBusinessError(EINVAL, true);
827         }
828         arg->errCode = gzclose(gzipEntity->gzs.get());
829         if (arg->errCode < 0) {
830             return NapiBusinessError(arg->errCode, true);
831         }
832         return NapiBusinessError(ERRNO_NOERR);
833     };
834 
835     auto cbCompl = [arg](napi_env env, NapiBusinessError err) -> NapiValue {
836         if (err) {
837             return {env, err.GetNapiErr(env)};
838         } else if (!arg) {
839             return {NapiValue::CreateUndefined(env)};
840         }
841         return {NapiValue::CreateInt32(env, arg->errCode)};
842     };
843 
844     NapiValue thisVar(env, funcArg.GetThisVar());
845     if (funcArg.GetArgc() == ArgumentCount::ZERO) {
846         return NapiAsyncWorkPromise(env, thisVar).Schedule(PROCEDURE_GZIP_NAME, cbExec, cbCompl).val_;
847     }
848 
849     return NapiValue::CreateUndefined(env).val_;
850 }
851 
GZCloseR(napi_env env,napi_callback_info info)852 napi_value GZipNExporter::GZCloseR(napi_env env, napi_callback_info info)
853 {
854     NapiFuncArg funcArg(env, info);
855     if (!funcArg.InitArgs(ArgumentCount::ZERO, ArgumentCount::ONE)) {
856         NapiBusinessError().ThrowErr(env, EINVAL);
857         return nullptr;
858     }
859 
860     auto arg = std::make_shared<AsyncGZipArg>();
861     /* To get entity */
862     auto gzipEntity = NapiClass::GetEntityOf<GZipEntity>(env, funcArg.GetThisVar());
863     if (!gzipEntity) {
864         NapiBusinessError().ThrowErr(env, EINVAL);
865         return nullptr;
866     }
867 
868     auto cbExec = [arg, gzipEntity](napi_env env) -> NapiBusinessError {
869         if (!gzipEntity) {
870             return NapiBusinessError(EINVAL, true);
871         }
872         arg->errCode = gzclose_r(gzipEntity->gzs.get());
873         if (arg->errCode < 0) {
874             return NapiBusinessError(arg->errCode, true);
875         }
876         return NapiBusinessError(ERRNO_NOERR);
877     };
878 
879     auto cbCompl = [arg](napi_env env, NapiBusinessError err) -> NapiValue {
880         if (err) {
881             return {env, err.GetNapiErr(env)};
882         } else if (!arg) {
883             return {NapiValue::CreateUndefined(env)};
884         }
885         return {NapiValue::CreateInt32(env, arg->errCode)};
886     };
887 
888     NapiValue thisVar(env, funcArg.GetThisVar());
889     if (funcArg.GetArgc() == ArgumentCount::ZERO) {
890         return NapiAsyncWorkPromise(env, thisVar).Schedule(PROCEDURE_GZIP_NAME, cbExec, cbCompl).val_;
891     }
892 
893     return NapiValue::CreateUndefined(env).val_;
894 }
895 
GZGetS(napi_env env,napi_callback_info info)896 napi_value GZipNExporter::GZGetS(napi_env env, napi_callback_info info)
897 {
898     NapiFuncArg funcArg(env, info);
899     if (!funcArg.InitArgs(ArgumentCount::ONE, ArgumentCount::TWO)) {
900         NapiBusinessError().ThrowErr(env, EINVAL);
901         return nullptr;
902     }
903     auto arg = std::make_shared<AsyncGZipArg>();
904     /* To get entity */
905     auto gzipEntity = NapiClass::GetEntityOf<GZipEntity>(env, funcArg.GetThisVar());
906     if (!gzipEntity) {
907         NapiBusinessError().ThrowErr(env, EINVAL);
908         return nullptr;
909     }
910     bool succ = false;
911     void *buffer = nullptr;
912     std::tie(succ, buffer, arg->bufLen) = CommonFunc::GetGZGetSArg(env, funcArg);
913     if (!succ) {
914         return nullptr;
915     }
916     auto cbExec = [arg, gzipEntity, buffer](napi_env env) -> NapiBusinessError {
917         if (!gzipEntity) {
918             return NapiBusinessError(EINVAL, true);
919         }
920         auto nullTerminatedString =
921             gzgets(gzipEntity->gzs.get(), reinterpret_cast<char *>(buffer), static_cast<int>(arg->bufLen));
922         if (!nullTerminatedString) {
923             return NapiBusinessError(ENOSTR, true);
924         }
925         arg->nullTerminatedString = nullTerminatedString;
926         return NapiBusinessError(ERRNO_NOERR);
927     };
928 
929     auto cbCompl = [arg](napi_env env, NapiBusinessError err) -> NapiValue {
930         if (err) {
931             return {env, err.GetNapiErr(env)};
932         } else if (!arg->nullTerminatedString) {
933             return {NapiValue::CreateUndefined(env)};
934         }
935         return {NapiValue::CreateUTF8String(env, arg->nullTerminatedString, strlen(arg->nullTerminatedString))};
936     };
937 
938     NapiValue thisVar(env, funcArg.GetThisVar());
939     if (funcArg.GetArgc() == ArgumentCount::ONE) {
940         return NapiAsyncWorkPromise(env, thisVar).Schedule(PROCEDURE_GZIP_NAME, cbExec, cbCompl).val_;
941     }
942 
943     return NapiValue::CreateUndefined(env).val_;
944 }
945 
GZGetC(napi_env env,napi_callback_info info)946 napi_value GZipNExporter::GZGetC(napi_env env, napi_callback_info info)
947 {
948     NapiFuncArg funcArg(env, info);
949     if (!funcArg.InitArgs(ArgumentCount::ZERO, ArgumentCount::ONE)) {
950         NapiBusinessError().ThrowErr(env, EINVAL);
951         return nullptr;
952     }
953 
954     auto arg = std::make_shared<AsyncGZipArg>();
955     /* To get entity */
956     auto gzipEntity = NapiClass::GetEntityOf<GZipEntity>(env, funcArg.GetThisVar());
957     if (!gzipEntity) {
958         NapiBusinessError().ThrowErr(env, EINVAL);
959         return nullptr;
960     }
961 
962     auto cbExec = [arg, gzipEntity](napi_env env) -> NapiBusinessError {
963         if (!gzipEntity) {
964             return NapiBusinessError(EINVAL, true);
965         }
966         arg->errCode = gzgetc(gzipEntity->gzs.get());
967         if (arg->errCode < 0) {
968             return NapiBusinessError(ENOSTR, true);
969         }
970         return NapiBusinessError(ERRNO_NOERR);
971     };
972 
973     auto cbCompl = [arg](napi_env env, NapiBusinessError err) -> NapiValue {
974         if (err) {
975             return {env, err.GetNapiErr(env)};
976         } else if (!arg) {
977             return {NapiValue::CreateUndefined(env)};
978         }
979         return {NapiValue::CreateInt32(env, arg->errCode)};
980     };
981 
982     NapiValue thisVar(env, funcArg.GetThisVar());
983     if (funcArg.GetArgc() == ArgumentCount::ZERO) {
984         return NapiAsyncWorkPromise(env, thisVar).Schedule(PROCEDURE_GZIP_NAME, cbExec, cbCompl).val_;
985     }
986 
987     return NapiValue::CreateUndefined(env).val_;
988 }
989 
GZRewind(napi_env env,napi_callback_info info)990 napi_value GZipNExporter::GZRewind(napi_env env, napi_callback_info info)
991 {
992     NapiFuncArg funcArg(env, info);
993     if (!funcArg.InitArgs(ArgumentCount::ZERO, ArgumentCount::ONE)) {
994         NapiBusinessError().ThrowErr(env, EINVAL);
995         return nullptr;
996     }
997 
998     auto arg = std::make_shared<AsyncGZipArg>();
999     /* To get entity */
1000     auto gzipEntity = NapiClass::GetEntityOf<GZipEntity>(env, funcArg.GetThisVar());
1001     if (!gzipEntity) {
1002         NapiBusinessError().ThrowErr(env, EINVAL);
1003         return nullptr;
1004     }
1005 
1006     auto cbExec = [arg, gzipEntity](napi_env env) -> NapiBusinessError {
1007         if (!gzipEntity) {
1008             return NapiBusinessError(EINVAL, true);
1009         }
1010         arg->errCode = gzrewind(gzipEntity->gzs.get());
1011         if (arg->errCode < 0) {
1012             return NapiBusinessError(ENOSTR, true);
1013         }
1014         return NapiBusinessError(ERRNO_NOERR);
1015     };
1016 
1017     auto cbCompl = [arg](napi_env env, NapiBusinessError err) -> NapiValue {
1018         if (err) {
1019             return {env, err.GetNapiErr(env)};
1020         } else if (!arg) {
1021             return {NapiValue::CreateUndefined(env)};
1022         }
1023         return {NapiValue::CreateInt32(env, arg->errCode)};
1024     };
1025 
1026     NapiValue thisVar(env, funcArg.GetThisVar());
1027     if (funcArg.GetArgc() == ArgumentCount::ZERO) {
1028         return NapiAsyncWorkPromise(env, thisVar).Schedule(PROCEDURE_GZIP_NAME, cbExec, cbCompl).val_;
1029     }
1030 
1031     return NapiValue::CreateUndefined(env).val_;
1032 }
1033 
GZSeek(napi_env env,napi_callback_info info)1034 napi_value GZipNExporter::GZSeek(napi_env env, napi_callback_info info)
1035 {
1036     NapiFuncArg funcArg(env, info);
1037     if (!funcArg.InitArgs(ArgumentCount::TWO, ArgumentCount::THREE)) {
1038         NapiBusinessError().ThrowErr(env, EINVAL);
1039         return nullptr;
1040     }
1041     auto arg = std::make_shared<AsyncGZipArg>();
1042     auto gzipEntity = NapiClass::GetEntityOf<GZipEntity>(env, funcArg.GetThisVar());
1043     if (!gzipEntity) {
1044         NapiBusinessError().ThrowErr(env, EINVAL);
1045         return nullptr;
1046     }
1047     bool succ = false;
1048     std::tie(succ, arg->seekOffset, arg->seekWhence) = CommonFunc::GetGZSeekArg(env, funcArg);
1049     if (!succ) {
1050         return nullptr;
1051     }
1052     auto cbExec = [arg, gzipEntity](napi_env env) -> NapiBusinessError {
1053         if (!gzipEntity) {
1054             return NapiBusinessError(EINVAL, true);
1055         }
1056 #if !defined(ZLIB_INTERNAL) && defined(Z_WANT64) && !defined(Z_LARGE64)
1057         arg->offset64 = gzseek64(gzipEntity->gzs.get(), arg->seekOffset, arg->seekWhence);
1058 #else
1059         arg->offset = gzseek(gzipEntity->gzs.get(), static_cast<long>(arg->seekOffset), arg->seekWhence);
1060 #endif
1061         if (arg->offset < 0 || arg->offset64 < 0) {
1062             return NapiBusinessError(ENOSTR, true);
1063         }
1064         return NapiBusinessError(ERRNO_NOERR);
1065     };
1066     auto cbCompl = [arg](napi_env env, NapiBusinessError err) -> NapiValue {
1067         if (err) {
1068             return {env, err.GetNapiErr(env)};
1069         } else if (!arg) {
1070             return {NapiValue::CreateUndefined(env)};
1071         }
1072 #if !defined(ZLIB_INTERNAL) && defined(Z_WANT64) && !defined(Z_LARGE64)
1073         return {NapiValue::CreateInt64(env, arg->offset64)};
1074 #else
1075         return {NapiValue::CreateInt32(env, arg->offset)};
1076 #endif
1077     };
1078     NapiValue thisVar(env, funcArg.GetThisVar());
1079     if (funcArg.GetArgc() == ArgumentCount::TWO) {
1080         return NapiAsyncWorkPromise(env, thisVar).Schedule(PROCEDURE_GZIP_NAME, cbExec, cbCompl).val_;
1081     }
1082     return NapiValue::CreateUndefined(env).val_;
1083 }
1084 
GZOffset(napi_env env,napi_callback_info info)1085 napi_value GZipNExporter::GZOffset(napi_env env, napi_callback_info info)
1086 {
1087     NapiFuncArg funcArg(env, info);
1088     if (!funcArg.InitArgs(ArgumentCount::ZERO, ArgumentCount::ONE)) {
1089         NapiBusinessError().ThrowErr(env, EINVAL);
1090         return nullptr;
1091     }
1092 
1093     auto arg = std::make_shared<AsyncGZipArg>();
1094     /* To get entity */
1095     auto gzipEntity = NapiClass::GetEntityOf<GZipEntity>(env, funcArg.GetThisVar());
1096     if (!gzipEntity) {
1097         NapiBusinessError().ThrowErr(env, EINVAL);
1098         return nullptr;
1099     }
1100 
1101     auto cbExec = [arg, gzipEntity](napi_env env) -> NapiBusinessError {
1102         if (!gzipEntity) {
1103             return NapiBusinessError(EINVAL, true);
1104         }
1105 #if !defined(ZLIB_INTERNAL) && defined(Z_WANT64) && !defined(Z_LARGE64)
1106         arg->offset64 = gzoffset64(gzipEntity->gzs.get());
1107 #else
1108         arg->offset = gzoffset(gzipEntity->gzs.get());
1109 #endif
1110         if (arg->offset < 0 || arg->offset64 < 0) {
1111             return NapiBusinessError(ENOSTR, true);
1112         }
1113         return NapiBusinessError(ERRNO_NOERR);
1114     };
1115 
1116     auto cbCompl = [arg](napi_env env, NapiBusinessError err) -> NapiValue {
1117         if (err) {
1118             return {env, err.GetNapiErr(env)};
1119         } else if (!arg) {
1120             return {NapiValue::CreateUndefined(env)};
1121         }
1122 #if !defined(ZLIB_INTERNAL) && defined(Z_WANT64) && !defined(Z_LARGE64)
1123         return {NapiValue::CreateInt64(env, arg->offset64)};
1124 #else
1125         return {NapiValue::CreateInt32(env, arg->offset)};
1126 #endif
1127     };
1128 
1129     NapiValue thisVar(env, funcArg.GetThisVar());
1130     if (funcArg.GetArgc() == ArgumentCount::ZERO) {
1131         return NapiAsyncWorkPromise(env, thisVar).Schedule(PROCEDURE_GZIP_NAME, cbExec, cbCompl).val_;
1132     }
1133 
1134     return NapiValue::CreateUndefined(env).val_;
1135 }
1136 
GZUnGetC(napi_env env,napi_callback_info info)1137 napi_value GZipNExporter::GZUnGetC(napi_env env, napi_callback_info info)
1138 {
1139     NapiFuncArg funcArg(env, info);
1140     if (!funcArg.InitArgs(ArgumentCount::ONE, ArgumentCount::TWO)) {
1141         NapiBusinessError().ThrowErr(env, EINVAL);
1142         return nullptr;
1143     }
1144 
1145     auto arg = std::make_shared<AsyncGZipArg>();
1146     auto gzipEntity = NapiClass::GetEntityOf<GZipEntity>(env, funcArg.GetThisVar());
1147     if (!gzipEntity) {
1148         NapiBusinessError().ThrowErr(env, EINVAL);
1149         return nullptr;
1150     }
1151 
1152     int32_t ascii = -1;
1153     bool succ = false;
1154     std::tie(succ, ascii) = CommonFunc::GetGZUnGetCArg(env, funcArg);
1155     if (!succ) {
1156         return nullptr;
1157     }
1158     auto cbExec = [arg, ascii, gzipEntity](napi_env env) -> NapiBusinessError {
1159         if (!gzipEntity) {
1160             return NapiBusinessError(EINVAL, true);
1161         }
1162         arg->character = gzungetc(ascii, gzipEntity->gzs.get());
1163         if (arg->character < 0) {
1164             return NapiBusinessError(ENOSTR, true);
1165         }
1166         return NapiBusinessError(ERRNO_NOERR);
1167     };
1168 
1169     auto cbCompl = [arg](napi_env env, NapiBusinessError err) -> NapiValue {
1170         if (err) {
1171             return {env, err.GetNapiErr(env)};
1172         } else if (!arg) {
1173             return {NapiValue::CreateUndefined(env)};
1174         }
1175         return {NapiValue::CreateInt32(env, arg->character)};
1176     };
1177 
1178     NapiValue thisVar(env, funcArg.GetThisVar());
1179     if (funcArg.GetArgc() == ArgumentCount::ONE) {
1180         return NapiAsyncWorkPromise(env, thisVar).Schedule(PROCEDURE_GZIP_NAME, cbExec, cbCompl).val_;
1181     }
1182 
1183     return NapiValue::CreateUndefined(env).val_;
1184 }
1185 
GZClearerr(napi_env env,napi_callback_info info)1186 napi_value GZipNExporter::GZClearerr(napi_env env, napi_callback_info info)
1187 {
1188     NapiFuncArg funcArg(env, info);
1189     if (!funcArg.InitArgs(ArgumentCount::ZERO, ArgumentCount::ONE)) {
1190         NapiBusinessError().ThrowErr(env, EINVAL);
1191         return nullptr;
1192     }
1193 
1194     auto arg = std::make_shared<AsyncGZipArg>();
1195     /* To get entity */
1196     auto gzipEntity = NapiClass::GetEntityOf<GZipEntity>(env, funcArg.GetThisVar());
1197     if (!gzipEntity) {
1198         NapiBusinessError().ThrowErr(env, EFAULT);
1199         return nullptr;
1200     }
1201 
1202     auto cbExec = [arg, gzipEntity](napi_env env) -> NapiBusinessError {
1203         if (!gzipEntity) {
1204             return NapiBusinessError(EFAULT, true);
1205         }
1206         gzclearerr(gzipEntity->gzs.get());
1207         return NapiBusinessError(ERRNO_NOERR);
1208     };
1209 
1210     auto cbCompl = [arg](napi_env env, NapiBusinessError err) -> NapiValue {
1211         if (err) {
1212             return {env, err.GetNapiErr(env)};
1213         } else if (!arg) {
1214             return {NapiValue::CreateUndefined(env)};
1215         }
1216         return {NapiValue::CreateUndefined(env)};
1217     };
1218 
1219     NapiValue thisVar(env, funcArg.GetThisVar());
1220     if (funcArg.GetArgc() == ArgumentCount::ZERO) {
1221         return NapiAsyncWorkPromise(env, thisVar).Schedule(PROCEDURE_GZIP_NAME, cbExec, cbCompl).val_;
1222     }
1223 
1224     return NapiValue::CreateUndefined(env).val_;
1225 }
1226 
GZDirect(napi_env env,napi_callback_info info)1227 napi_value GZipNExporter::GZDirect(napi_env env, napi_callback_info info)
1228 {
1229     NapiFuncArg funcArg(env, info);
1230     if (!funcArg.InitArgs(ArgumentCount::ZERO, ArgumentCount::ONE)) {
1231         NapiBusinessError().ThrowErr(env, EINVAL);
1232         return nullptr;
1233     }
1234 
1235     auto arg = std::make_shared<AsyncGZipArg>();
1236     /* To get entity */
1237     auto gzipEntity = NapiClass::GetEntityOf<GZipEntity>(env, funcArg.GetThisVar());
1238     if (!gzipEntity) {
1239         NapiBusinessError().ThrowErr(env, EFAULT);
1240         return nullptr;
1241     }
1242 
1243     auto cbExec = [arg, gzipEntity](napi_env env) -> NapiBusinessError {
1244         if (!gzipEntity) {
1245             return NapiBusinessError(EFAULT, true);
1246         }
1247         arg->errCode = gzdirect(gzipEntity->gzs.get());
1248         if (arg->errCode < 0) {
1249             return NapiBusinessError(arg->errCode, true);
1250         }
1251         return NapiBusinessError(ERRNO_NOERR);
1252     };
1253 
1254     auto cbCompl = [arg](napi_env env, NapiBusinessError err) -> NapiValue {
1255         if (err) {
1256             return {env, err.GetNapiErr(env)};
1257         } else if (!arg) {
1258             return {NapiValue::CreateUndefined(env)};
1259         }
1260         return {NapiValue::CreateInt32(env, arg->errCode)};
1261     };
1262 
1263     NapiValue thisVar(env, funcArg.GetThisVar());
1264     if (funcArg.GetArgc() == ArgumentCount::ZERO) {
1265         return NapiAsyncWorkPromise(env, thisVar).Schedule(PROCEDURE_GZIP_NAME, cbExec, cbCompl).val_;
1266     }
1267 
1268     return NapiValue::CreateUndefined(env).val_;
1269 }
1270 
GZeof(napi_env env,napi_callback_info info)1271 napi_value GZipNExporter::GZeof(napi_env env, napi_callback_info info)
1272 {
1273     NapiFuncArg funcArg(env, info);
1274     if (!funcArg.InitArgs(ArgumentCount::ZERO, ArgumentCount::ONE)) {
1275         NapiBusinessError().ThrowErr(env, EINVAL);
1276         return nullptr;
1277     }
1278 
1279     auto arg = std::make_shared<AsyncGZipArg>();
1280     /* To get entity */
1281     auto gzipEntity = NapiClass::GetEntityOf<GZipEntity>(env, funcArg.GetThisVar());
1282     if (!gzipEntity) {
1283         NapiBusinessError().ThrowErr(env, EFAULT);
1284         return nullptr;
1285     }
1286 
1287     auto cbExec = [arg, gzipEntity](napi_env env) -> NapiBusinessError {
1288         if (!gzipEntity) {
1289             return NapiBusinessError(EFAULT, true);
1290         }
1291         arg->errCode = gzeof(gzipEntity->gzs.get());
1292         if (arg->errCode < 0) {
1293             return NapiBusinessError(arg->errCode, true);
1294         }
1295         return NapiBusinessError(ERRNO_NOERR);
1296     };
1297 
1298     auto cbCompl = [arg](napi_env env, NapiBusinessError err) -> NapiValue {
1299         if (err) {
1300             return {env, err.GetNapiErr(env)};
1301         } else if (!arg) {
1302             return {NapiValue::CreateUndefined(env)};
1303         }
1304         return {NapiValue::CreateInt32(env, arg->errCode)};
1305     };
1306 
1307     NapiValue thisVar(env, funcArg.GetThisVar());
1308     if (funcArg.GetArgc() == ArgumentCount::ZERO) {
1309         return NapiAsyncWorkPromise(env, thisVar).Schedule(PROCEDURE_GZIP_NAME, cbExec, cbCompl).val_;
1310     }
1311 
1312     return NapiValue::CreateUndefined(env).val_;
1313 }
1314 
CreateGzErrorOutputInfoObject(napi_env env,const AsyncGZipArg * arg)1315 static NapiValue CreateGzErrorOutputInfoObject(napi_env env, const AsyncGZipArg *arg)
1316 {
1317     /* To get entity */
1318     if (!arg) {
1319         NapiBusinessError().ThrowErr(env, EFAULT);
1320         return NapiValue(env, nullptr);
1321     }
1322 
1323     NapiValue obj = NapiValue::CreateObject(env);
1324     obj.AddProp({
1325         NapiValue::DeclareNapiProperty("status", NapiValue::CreateInt64(env, arg->errCode).val_),
1326         NapiValue::DeclareNapiProperty("statusMsg",
1327             NapiValue::CreateUTF8String(env, reinterpret_cast<const char *>(arg->errMsg), strlen(arg->errMsg)).val_),
1328     });
1329 
1330     return obj;
1331 }
1332 
GZError(napi_env env,napi_callback_info info)1333 napi_value GZipNExporter::GZError(napi_env env, napi_callback_info info)
1334 {
1335     NapiFuncArg funcArg(env, info);
1336     if (!funcArg.InitArgs(ArgumentCount::ZERO, ArgumentCount::ONE)) {
1337         NapiBusinessError().ThrowErr(env, EINVAL);
1338         return nullptr;
1339     }
1340 
1341     auto arg = std::make_shared<AsyncGZipArg>();
1342     /* To get entity */
1343     auto gzipEntity = NapiClass::GetEntityOf<GZipEntity>(env, funcArg.GetThisVar());
1344     if (!gzipEntity) {
1345         NapiBusinessError().ThrowErr(env, EFAULT);
1346         return nullptr;
1347     }
1348 
1349     auto cbExec = [arg, gzipEntity](napi_env env) -> NapiBusinessError {
1350         if (!gzipEntity) {
1351             return NapiBusinessError(EFAULT, true);
1352         }
1353         arg->errMsg = gzerror(gzipEntity->gzs.get(), &arg->errCode);
1354         if (arg->errMsg == nullptr) {
1355             return NapiBusinessError(EZSTREAM_ERROR, true);
1356         }
1357         return NapiBusinessError(ERRNO_NOERR);
1358     };
1359 
1360     auto cbCompl = [arg](napi_env env, NapiBusinessError err) -> NapiValue {
1361         if (err) {
1362             return {env, err.GetNapiErr(env)};
1363         } else if (!arg->errMsg) {
1364             return {NapiValue::CreateUndefined(env)};
1365         }
1366         return {CreateGzErrorOutputInfoObject(env, arg.get())};
1367     };
1368 
1369     NapiValue thisVar(env, funcArg.GetThisVar());
1370     if (funcArg.GetArgc() == ArgumentCount::ZERO) {
1371         return NapiAsyncWorkPromise(env, thisVar).Schedule(PROCEDURE_GZIP_NAME, cbExec, cbCompl).val_;
1372     }
1373 
1374     return NapiValue::CreateUndefined(env).val_;
1375 }
1376 
GZFlush(napi_env env,napi_callback_info info)1377 napi_value GZipNExporter::GZFlush(napi_env env, napi_callback_info info)
1378 {
1379     NapiFuncArg funcArg(env, info);
1380     if (!funcArg.InitArgs(ArgumentCount::ONE, ArgumentCount::TWO)) {
1381         NapiBusinessError().ThrowErr(env, EINVAL);
1382         return nullptr;
1383     }
1384 
1385     auto arg = std::make_shared<AsyncGZipArg>();
1386     /* To get entity */
1387     auto gzipEntity = NapiClass::GetEntityOf<GZipEntity>(env, funcArg.GetThisVar());
1388     if (!gzipEntity) {
1389         NapiBusinessError().ThrowErr(env, EFAULT);
1390         return nullptr;
1391     }
1392 
1393     bool succ = false;
1394     uint32_t flush = 0;
1395     std::tie(succ, flush) = CommonFunc::SetGZFlushArg(env, funcArg);
1396     if (!succ) {
1397         return nullptr;
1398     }
1399 
1400     auto cbExec = [arg, gzipEntity, flush](napi_env env) -> NapiBusinessError {
1401         if (!gzipEntity) {
1402             return NapiBusinessError(EFAULT, true);
1403         }
1404         arg->errCode = gzflush(gzipEntity->gzs.get(), flush);
1405         if (arg->errCode < 0) {
1406             return NapiBusinessError(arg->errCode, true);
1407         }
1408         return NapiBusinessError(ERRNO_NOERR);
1409     };
1410 
1411     auto cbCompl = [arg](napi_env env, NapiBusinessError err) -> NapiValue {
1412         if (err) {
1413             return {env, err.GetNapiErr(env)};
1414         } else if (!arg) {
1415             return {NapiValue::CreateUndefined(env)};
1416         }
1417         return {NapiValue::CreateInt32(env, arg->errCode)};
1418     };
1419 
1420     NapiValue thisVar(env, funcArg.GetThisVar());
1421     if (funcArg.GetArgc() == ArgumentCount::ONE) {
1422         return NapiAsyncWorkPromise(env, thisVar).Schedule(PROCEDURE_GZIP_NAME, cbExec, cbCompl).val_;
1423     }
1424 
1425     return NapiValue::CreateUndefined(env).val_;
1426 }
1427 
1428 }  // namespace LIBZIP
1429 }  // namespace AppExecFwk
1430 }  // namespace OHOS
1431