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