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 "checksum_n_exporter.h"
17 
18 #include <cstdio>
19 #include <cstdlib>
20 #include <cstring>
21 #include <memory>
22 #include <sstream>
23 #include <string>
24 #include <tuple>
25 
26 #include "common/common_func.h"
27 #include "common/napi_async_work_callback.h"
28 #include "common/napi_async_work_promise.h"
29 #include "common/napi_class.h"
30 #include "common/napi_func_arg.h"
31 #include "common/napi_business_error.h"
32 #include "checksum_entity.h"
33 #include "zlib.h"
34 
35 namespace OHOS {
36 namespace AppExecFwk {
37 namespace LIBZIP {
38 using namespace std;
39 
40 constexpr int32_t SHIFT_AMOUNT = 8;
41 constexpr uint64_t CRC64_TABLE[] = {
42     0x0000000000000000, 0x3c3b78e888d80fe1, 0x7876f1d111b01fc2, 0x444d893999681023,
43     0x750c207570b452a3, 0x4937589df86c5d42, 0x0d7ad1a461044d61, 0x3141a94ce9dc4280,
44     0x6ff9833db2bcc861, 0x53c2fbd53a64c780, 0x178f72eca30cd7a3, 0x2bb40a042bd4d842,
45     0x1af5a348c2089ac2, 0x26cedba04ad09523, 0x62835299d3b88500, 0x5eb82a715b608ae1,
46     0x5a12c5ac36adfde5, 0x6629bd44be75f204, 0x2264347d271de227, 0x1e5f4c95afc5edc6,
47     0x2f1ee5d94619af46, 0x13259d31cec1a0a7, 0x5768140857a9b084, 0x6b536ce0df71bf65,
48     0x35eb469184113584, 0x09d03e790cc93a65, 0x4d9db74095a12a46, 0x71a6cfa81d7925a7,
49     0x40e766e4f4a56727, 0x7cdc1e0c7c7d68c6, 0x38919735e51578e5, 0x04aaefdd6dcd7704,
50     0x31c4488f3e8f96ed, 0x0dff3067b657990c, 0x49b2b95e2f3f892f, 0x7589c1b6a7e786ce,
51     0x44c868fa4e3bc44e, 0x78f31012c6e3cbaf, 0x3cbe992b5f8bdb8c, 0x0085e1c3d753d46d,
52     0x5e3dcbb28c335e8c, 0x6206b35a04eb516d, 0x264b3a639d83414e, 0x1a70428b155b4eaf,
53     0x2b31ebc7fc870c2f, 0x170a932f745f03ce, 0x53471a16ed3713ed, 0x6f7c62fe65ef1c0c,
54     0x6bd68d2308226b08, 0x57edf5cb80fa64e9, 0x13a07cf2199274ca, 0x2f9b041a914a7b2b,
55     0x1edaad56789639ab, 0x22e1d5bef04e364a, 0x66ac5c8769262669, 0x5a97246fe1fe2988,
56     0x042f0e1eba9ea369, 0x381476f63246ac88, 0x7c59ffcfab2ebcab, 0x4062872723f6b34a,
57     0x71232e6bca2af1ca, 0x4d18568342f2fe2b, 0x0955dfbadb9aee08, 0x356ea7525342e1e9,
58     0x6388911e7d1f2dda, 0x5fb3e9f6f5c7223b, 0x1bfe60cf6caf3218, 0x27c51827e4773df9,
59     0x1684b16b0dab7f79, 0x2abfc98385737098, 0x6ef240ba1c1b60bb, 0x52c9385294c36f5a,
60     0x0c711223cfa3e5bb, 0x304a6acb477bea5a, 0x7407e3f2de13fa79, 0x483c9b1a56cbf598,
61     0x797d3256bf17b718, 0x45464abe37cfb8f9, 0x010bc387aea7a8da, 0x3d30bb6f267fa73b,
62     0x399a54b24bb2d03f, 0x05a12c5ac36adfde, 0x41eca5635a02cffd, 0x7dd7dd8bd2dac01c,
63     0x4c9674c73b06829c, 0x70ad0c2fb3de8d7d, 0x34e085162ab69d5e, 0x08dbfdfea26e92bf,
64     0x5663d78ff90e185e, 0x6a58af6771d617bf, 0x2e15265ee8be079c, 0x122e5eb66066087d,
65     0x236ff7fa89ba4afd, 0x1f548f120162451c, 0x5b19062b980a553f, 0x67227ec310d25ade,
66     0x524cd9914390bb37, 0x6e77a179cb48b4d6, 0x2a3a28405220a4f5, 0x160150a8daf8ab14,
67     0x2740f9e43324e994, 0x1b7b810cbbfce675, 0x5f3608352294f656, 0x630d70ddaa4cf9b7,
68     0x3db55aacf12c7356, 0x018e224479f47cb7, 0x45c3ab7de09c6c94, 0x79f8d39568446375,
69     0x48b97ad9819821f5, 0x7482023109402e14, 0x30cf8b0890283e37, 0x0cf4f3e018f031d6,
70     0x085e1c3d753d46d2, 0x346564d5fde54933, 0x7028edec648d5910, 0x4c139504ec5556f1,
71     0x7d523c4805891471, 0x416944a08d511b90, 0x0524cd9914390bb3, 0x391fb5719ce10452,
72     0x67a79f00c7818eb3, 0x5b9ce7e84f598152, 0x1fd16ed1d6319171, 0x23ea16395ee99e90,
73     0x12abbf75b735dc10, 0x2e90c79d3fedd3f1, 0x6add4ea4a685c3d2, 0x56e6364c2e5dcc33,
74     0x42f0e1eba9ea3693, 0x7ecb990321323972, 0x3a86103ab85a2951, 0x06bd68d2308226b0,
75     0x37fcc19ed95e6430, 0x0bc7b97651866bd1, 0x4f8a304fc8ee7bf2, 0x73b148a740367413,
76     0x2d0962d61b56fef2, 0x11321a3e938ef113, 0x557f93070ae6e130, 0x6944ebef823eeed1,
77     0x580542a36be2ac51, 0x643e3a4be33aa3b0, 0x2073b3727a52b393, 0x1c48cb9af28abc72,
78     0x18e224479f47cb76, 0x24d95caf179fc497, 0x6094d5968ef7d4b4, 0x5cafad7e062fdb55,
79     0x6dee0432eff399d5, 0x51d57cda672b9634, 0x1598f5e3fe438617, 0x29a38d0b769b89f6,
80     0x771ba77a2dfb0317, 0x4b20df92a5230cf6, 0x0f6d56ab3c4b1cd5, 0x33562e43b4931334,
81     0x0217870f5d4f51b4, 0x3e2cffe7d5975e55, 0x7a6176de4cff4e76, 0x465a0e36c4274197,
82     0x7334a9649765a07e, 0x4f0fd18c1fbdaf9f, 0x0b4258b586d5bfbc, 0x3779205d0e0db05d,
83     0x06388911e7d1f2dd, 0x3a03f1f96f09fd3c, 0x7e4e78c0f661ed1f, 0x427500287eb9e2fe,
84     0x1ccd2a5925d9681f, 0x20f652b1ad0167fe, 0x64bbdb88346977dd, 0x5880a360bcb1783c,
85     0x69c10a2c556d3abc, 0x55fa72c4ddb5355d, 0x11b7fbfd44dd257e, 0x2d8c8315cc052a9f,
86     0x29266cc8a1c85d9b, 0x151d14202910527a, 0x51509d19b0784259, 0x6d6be5f138a04db8,
87     0x5c2a4cbdd17c0f38, 0x6011345559a400d9, 0x245cbd6cc0cc10fa, 0x1867c58448141f1b,
88     0x46dfeff5137495fa, 0x7ae4971d9bac9a1b, 0x3ea91e2402c48a38, 0x029266cc8a1c85d9,
89     0x33d3cf8063c0c759, 0x0fe8b768eb18c8b8, 0x4ba53e517270d89b, 0x779e46b9faa8d77a,
90     0x217870f5d4f51b49, 0x1d43081d5c2d14a8, 0x590e8124c545048b, 0x6535f9cc4d9d0b6a,
91     0x54745080a44149ea, 0x684f28682c99460b, 0x2c02a151b5f15628, 0x1039d9b93d2959c9,
92     0x4e81f3c86649d328, 0x72ba8b20ee91dcc9, 0x36f7021977f9ccea, 0x0acc7af1ff21c30b,
93     0x3b8dd3bd16fd818b, 0x07b6ab559e258e6a, 0x43fb226c074d9e49, 0x7fc05a848f9591a8,
94     0x7b6ab559e258e6ac, 0x4751cdb16a80e94d, 0x031c4488f3e8f96e, 0x3f273c607b30f68f,
95     0x0e66952c92ecb40f, 0x325dedc41a34bbee, 0x761064fd835cabcd, 0x4a2b1c150b84a42c,
96     0x1493366450e42ecd, 0x28a84e8cd83c212c, 0x6ce5c7b54154310f, 0x50debf5dc98c3eee,
97     0x619f161120507c6e, 0x5da46ef9a888738f, 0x19e9e7c031e063ac, 0x25d29f28b9386c4d,
98     0x10bc387aea7a8da4, 0x2c87409262a28245, 0x68cac9abfbca9266, 0x54f1b14373129d87,
99     0x65b0180f9acedf07, 0x598b60e71216d0e6, 0x1dc6e9de8b7ec0c5, 0x21fd913603a6cf24,
100     0x7f45bb4758c645c5, 0x437ec3afd01e4a24, 0x07334a9649765a07, 0x3b08327ec1ae55e6,
101     0x0a499b3228721766, 0x3672e3daa0aa1887, 0x723f6ae339c208a4, 0x4e04120bb11a0745,
102     0x4aaefdd6dcd77041, 0x7695853e540f7fa0, 0x32d80c07cd676f83, 0x0ee374ef45bf6062,
103     0x3fa2dda3ac6322e2, 0x0399a54b24bb2d03, 0x47d42c72bdd33d20, 0x7bef549a350b32c1,
104     0x25577eeb6e6bb820, 0x196c0603e6b3b7c1, 0x5d218f3a7fdba7e2, 0x611af7d2f703a803,
105     0x505b5e9e1edfea83, 0x6c6026769607e562, 0x282daf4f0f6ff541, 0x1416d7a787b7faa0
106 };
107 
108 struct AsyncChecksumArg {
109     uint64_t adler{0U};
110     const z_crc_t* crcTable = nullptr;
111 
112     AsyncChecksumArg() = default;
113     ~AsyncChecksumArg() = default;
114 };
115 
ComputeCrc64(uint64_t initCrc,const char * data,size_t length)116 static uint64_t ComputeCrc64(uint64_t initCrc, const char *data, size_t length)
117 {
118     uint64_t crc = initCrc;
119 
120     /* computation of the CRC */
121     for (size_t i = 0; i < length; ++i) {
122         crc = CRC64_TABLE[(crc ^ data[i]) & 0xFF] ^ (crc >> SHIFT_AMOUNT);
123     }
124 
125     return crc;
126 }
127 
Constructor(napi_env env,napi_callback_info info)128 napi_value ChecksumNExporter::Constructor(napi_env env, napi_callback_info info)
129 {
130     NapiFuncArg funcArg(env, info);
131     if (!funcArg.InitArgs(ArgumentCount::ZERO)) {
132         NapiBusinessError().ThrowErr(env, EINVAL);
133         return nullptr;
134     }
135 
136     unique_ptr<ChecksumEntity> checksumEntity = make_unique<ChecksumEntity>();
137     if (!NapiClass::SetEntityFor<ChecksumEntity>(env, funcArg.GetThisVar(), move(checksumEntity))) {
138         NapiBusinessError().ThrowErr(env, EFAULT);
139         return nullptr;
140     }
141     return funcArg.GetThisVar();
142 }
143 
Export()144 bool ChecksumNExporter::Export()
145 {
146     vector<napi_property_descriptor> props = {
147         NapiValue::DeclareNapiFunction("adler32", Adler32),
148         NapiValue::DeclareNapiFunction("adler32Combine", Adler32Combine),
149         NapiValue::DeclareNapiFunction("adler32Combine64", Adler32Combine64),
150         NapiValue::DeclareNapiFunction("crc32", Crc32),
151         NapiValue::DeclareNapiFunction("crc32Combine", Crc32Combine),
152         NapiValue::DeclareNapiFunction("crc32Combine64", Crc32Combine64),
153         NapiValue::DeclareNapiFunction("getCrcTable", GetCrcTable),
154         NapiValue::DeclareNapiFunction("getCrc64Table", GetCrc64Table),
155         NapiValue::DeclareNapiFunction("crc64", Crc64),
156     };
157 
158     string className = GetClassName();
159     bool succ = false;
160     napi_value cls = nullptr;
161     tie(succ, cls) = NapiClass::DefineClass(exports_.env_, className, ChecksumNExporter::Constructor, move(props));
162     if (!succ) {
163         NapiBusinessError().ThrowErr(exports_.env_, EFAULT);
164         return false;
165     }
166     succ = NapiClass::SaveClass(exports_.env_, className, cls);
167     if (!succ) {
168         NapiBusinessError().ThrowErr(exports_.env_, EFAULT);
169         return false;
170     }
171 
172     return exports_.AddProp(className, cls);
173 }
174 
GetClassName()175 string ChecksumNExporter::GetClassName()
176 {
177     return ChecksumNExporter::className_;
178 }
179 
ChecksumNExporter(napi_env env,napi_value exports)180 ChecksumNExporter::ChecksumNExporter(napi_env env, napi_value exports) : NapiExporter(env, exports)
181 {}
182 
~ChecksumNExporter()183 ChecksumNExporter::~ChecksumNExporter()
184 {}
185 
Adler32(napi_env env,napi_callback_info info)186 napi_value ChecksumNExporter::Adler32(napi_env env, napi_callback_info info)
187 {
188     NapiFuncArg funcArg(env, info);
189     if (!funcArg.InitArgs(ArgumentCount::TWO, ArgumentCount::THREE)) {
190         NapiBusinessError().ThrowErr(env, EINVAL);
191         return nullptr;
192     }
193 
194     /* To get entity */
195     auto checksumEntity = NapiClass::GetEntityOf<ChecksumEntity>(env, funcArg.GetThisVar());
196     if (!checksumEntity) {
197         NapiBusinessError().ThrowErr(env, EFAULT);
198         return nullptr;
199     }
200 
201     bool succ = false;
202     void *buf = nullptr;
203     size_t len = 0;
204     uLong adler = 0U;
205     tie(succ, adler, buf, len) = CommonFunc::GetAdler32Arg(env, funcArg);
206     if (!succ) {
207         return nullptr;
208     }
209 
210     auto arg = make_shared<AsyncChecksumArg>();
211     auto cbExec = [arg, adler, buf, len](napi_env env) -> NapiBusinessError {
212         if (!arg) {
213             return NapiBusinessError(EFAULT, true);
214         }
215         arg->adler = adler32(static_cast<uLong>(adler), reinterpret_cast<Bytef *>(buf), static_cast<uInt>(len));
216         return NapiBusinessError(ERRNO_NOERR);
217     };
218 
219     auto cbCompl = [arg](napi_env env, NapiBusinessError err) -> NapiValue {
220         if (err) {
221             return {env, err.GetNapiErr(env)};
222         }
223         if (!arg) {
224             return {NapiValue::CreateUndefined(env)};
225         }
226         return {NapiValue::CreateInt64(env, arg->adler)};
227     };
228 
229     NapiValue thisVar(env, funcArg.GetThisVar());
230     if (funcArg.GetArgc() == ArgumentCount::TWO) {
231         return NapiAsyncWorkPromise(env, thisVar).Schedule(PROCEDURE_CHECKSUM_NAME, cbExec, cbCompl).val_;
232     } else {
233         NapiValue cb(env, funcArg[ArgumentPosition::THIRD]);
234         return NapiAsyncWorkCallback(env, thisVar, cb).Schedule(PROCEDURE_CHECKSUM_NAME, cbExec, cbCompl).val_;
235     }
236 
237     return NapiValue::CreateUndefined(env).val_;
238 }
239 
Adler32Combine(napi_env env,napi_callback_info info)240 napi_value ChecksumNExporter::Adler32Combine(napi_env env, napi_callback_info info)
241 {
242     NapiFuncArg funcArg(env, info);
243     if (!funcArg.InitArgs(ArgumentCount::THREE, ArgumentCount::FOUR)) {
244         NapiBusinessError().ThrowErr(env, EINVAL);
245         return nullptr;
246     }
247 
248     /* To get entity */
249     auto checksumEntity = NapiClass::GetEntityOf<ChecksumEntity>(env, funcArg.GetThisVar());
250     if (!checksumEntity) {
251         NapiBusinessError().ThrowErr(env, EFAULT);
252         return nullptr;
253     }
254 
255     bool succ = false;
256     size_t len = 0;
257     uLong adler1 = 0U;
258     uLong adler2 = 0U;
259     tie(succ, adler1, adler2, len) = CommonFunc::GetAdler32CombineArg(env, funcArg);
260     if (!succ) {
261         return nullptr;
262     }
263 
264     auto arg = make_shared<AsyncChecksumArg>();
265     auto cbExec = [arg, adler1, adler2, len](napi_env env) -> NapiBusinessError {
266         if (!arg) {
267             return NapiBusinessError(EFAULT, true);
268         }
269 #ifdef Z_LARGE64
270         arg->adler = adler32_combine64(static_cast<uLong>(adler1), static_cast<uLong>(adler2), static_cast<uInt>(len));
271 #else
272         arg->adler = adler32_combine(static_cast<uLong>(adler1), static_cast<uLong>(adler2), static_cast<uInt>(len));
273 #endif
274         return NapiBusinessError(ERRNO_NOERR);
275     };
276 
277     auto cbCompl = [arg](napi_env env, NapiBusinessError err) -> NapiValue {
278         if (err) {
279             return {env, err.GetNapiErr(env)};
280         }
281         if (!arg) {
282             return {NapiValue::CreateUndefined(env)};
283         }
284         return {NapiValue::CreateInt64(env, arg->adler)};
285     };
286 
287     NapiValue thisVar(env, funcArg.GetThisVar());
288     if (funcArg.GetArgc() == ArgumentCount::THREE) {
289         return NapiAsyncWorkPromise(env, thisVar).Schedule(PROCEDURE_CHECKSUM_NAME, cbExec, cbCompl).val_;
290     } else {
291         NapiValue cb(env, funcArg[ArgumentPosition::FOURTH]);
292         return NapiAsyncWorkCallback(env, thisVar, cb).Schedule(PROCEDURE_CHECKSUM_NAME, cbExec, cbCompl).val_;
293     }
294 
295     return NapiValue::CreateUndefined(env).val_;
296 }
297 
Adler32Combine64(napi_env env,napi_callback_info info)298 napi_value ChecksumNExporter::Adler32Combine64(napi_env env, napi_callback_info info)
299 {
300     NapiFuncArg funcArg(env, info);
301     if (!funcArg.InitArgs(ArgumentCount::THREE, ArgumentCount::FOUR)) {
302         NapiBusinessError().ThrowErr(env, EINVAL);
303         return nullptr;
304     }
305 
306     /* To get entity */
307     auto checksumEntity = NapiClass::GetEntityOf<ChecksumEntity>(env, funcArg.GetThisVar());
308     if (!checksumEntity) {
309         NapiBusinessError().ThrowErr(env, EFAULT);
310         return nullptr;
311     }
312 
313     bool succ = false;
314     size_t len = 0;
315     uLong adler1 = 0U;
316     uLong adler2 = 0U;
317     tie(succ, adler1, adler2, len) = CommonFunc::GetAdler32CombineArg(env, funcArg);
318     if (!succ) {
319         return nullptr;
320     }
321 
322     auto arg = make_shared<AsyncChecksumArg>();
323     auto cbExec = [arg, adler1, adler2, len](napi_env env) -> NapiBusinessError {
324         if (!arg) {
325             return NapiBusinessError(EFAULT, true);
326         }
327         arg->adler = adler32_combine(static_cast<uLong>(adler1), static_cast<uLong>(adler2), static_cast<uInt>(len));
328         return NapiBusinessError(ERRNO_NOERR);
329     };
330 
331     auto cbCompl = [arg](napi_env env, NapiBusinessError err) -> NapiValue {
332         if (err) {
333             return {env, err.GetNapiErr(env)};
334         }
335         if (!arg) {
336             return {NapiValue::CreateUndefined(env)};
337         }
338         return {NapiValue::CreateInt64(env, arg->adler)};
339     };
340 
341     NapiValue thisVar(env, funcArg.GetThisVar());
342     if (funcArg.GetArgc() == ArgumentCount::THREE) {
343         return NapiAsyncWorkPromise(env, thisVar).Schedule(PROCEDURE_CHECKSUM_NAME, cbExec, cbCompl).val_;
344     } else {
345         NapiValue cb(env, funcArg[ArgumentPosition::FOURTH]);
346         return NapiAsyncWorkCallback(env, thisVar, cb).Schedule(PROCEDURE_CHECKSUM_NAME, cbExec, cbCompl).val_;
347     }
348 
349     return NapiValue::CreateUndefined(env).val_;
350 }
351 
Crc32(napi_env env,napi_callback_info info)352 napi_value ChecksumNExporter::Crc32(napi_env env, napi_callback_info info)
353 {
354     NapiFuncArg funcArg(env, info);
355     if (!funcArg.InitArgs(ArgumentCount::TWO, ArgumentCount::THREE)) {
356         NapiBusinessError().ThrowErr(env, EINVAL);
357         return nullptr;
358     }
359 
360     /* To get entity */
361     auto checksumEntity = NapiClass::GetEntityOf<ChecksumEntity>(env, funcArg.GetThisVar());
362     if (!checksumEntity) {
363         NapiBusinessError().ThrowErr(env, EFAULT);
364         return nullptr;
365     }
366 
367     bool succ = false;
368     void *buf = nullptr;
369     size_t len = 0;
370     uLong adler = 0U;
371     tie(succ, adler, buf, len) = CommonFunc::GetAdler32Arg(env, funcArg);
372     if (!succ) {
373         return nullptr;
374     }
375 
376     auto arg = make_shared<AsyncChecksumArg>();
377     auto cbExec = [arg, adler, buf, len](napi_env env) -> NapiBusinessError {
378         if (!arg) {
379             return NapiBusinessError(EFAULT, true);
380         }
381         arg->adler = crc32(static_cast<uLong>(adler), reinterpret_cast<Bytef *>(buf), static_cast<uInt>(len));
382         return NapiBusinessError(ERRNO_NOERR);
383     };
384 
385     auto cbCompl = [arg](napi_env env, NapiBusinessError err) -> NapiValue {
386         if (err) {
387             return {env, err.GetNapiErr(env)};
388         }
389         if (!arg) {
390             return {NapiValue::CreateUndefined(env)};
391         }
392         return {NapiValue::CreateInt64(env, arg->adler)};
393     };
394 
395     NapiValue thisVar(env, funcArg.GetThisVar());
396     if (funcArg.GetArgc() == ArgumentCount::TWO) {
397         return NapiAsyncWorkPromise(env, thisVar).Schedule(PROCEDURE_CHECKSUM_NAME, cbExec, cbCompl).val_;
398     } else {
399         NapiValue cb(env, funcArg[ArgumentPosition::THIRD]);
400         return NapiAsyncWorkCallback(env, thisVar, cb).Schedule(PROCEDURE_CHECKSUM_NAME, cbExec, cbCompl).val_;
401     }
402 
403     return NapiValue::CreateUndefined(env).val_;
404 }
405 
Crc32Combine(napi_env env,napi_callback_info info)406 napi_value ChecksumNExporter::Crc32Combine(napi_env env, napi_callback_info info)
407 {
408     NapiFuncArg funcArg(env, info);
409     if (!funcArg.InitArgs(ArgumentCount::THREE, ArgumentCount::FOUR)) {
410         NapiBusinessError().ThrowErr(env, EINVAL);
411         return nullptr;
412     }
413 
414     /* To get entity */
415     auto checksumEntity = NapiClass::GetEntityOf<ChecksumEntity>(env, funcArg.GetThisVar());
416     if (!checksumEntity) {
417         NapiBusinessError().ThrowErr(env, EFAULT);
418         return nullptr;
419     }
420 
421     bool succ = false;
422     int64_t len = 0;
423     uLong adler1 = 0U;
424     uLong adler2 = 0U;
425     tie(succ, adler1, adler2, len) = CommonFunc::GetAdler32CombineArg(env, funcArg);
426     if (!succ) {
427         return nullptr;
428     }
429 
430     auto arg = make_shared<AsyncChecksumArg>();
431     auto cbExec = [arg, adler1, adler2, len](napi_env env) -> NapiBusinessError {
432         if (!arg) {
433             return NapiBusinessError(EFAULT, true);
434         }
435 #ifdef Z_LARGE64
436         arg->adler =
437             crc32_combine64(static_cast<uLong>(adler1), static_cast<uLong>(adler2), static_cast<z_off64_t>(len));
438 #else
439         arg->adler = crc32_combine(static_cast<uLong>(adler1), static_cast<uLong>(adler2), static_cast<z_off_t>(len));
440 #endif
441         return NapiBusinessError(ERRNO_NOERR);
442     };
443 
444     auto cbCompl = [arg](napi_env env, NapiBusinessError err) -> NapiValue {
445         if (err) {
446             return {env, err.GetNapiErr(env)};
447         }
448         if (!arg) {
449             return {NapiValue::CreateUndefined(env)};
450         }
451         return {NapiValue::CreateInt64(env, arg->adler)};
452     };
453 
454     NapiValue thisVar(env, funcArg.GetThisVar());
455     if (funcArg.GetArgc() == ArgumentCount::THREE) {
456         return NapiAsyncWorkPromise(env, thisVar).Schedule(PROCEDURE_CHECKSUM_NAME, cbExec, cbCompl).val_;
457     } else {
458         NapiValue cb(env, funcArg[ArgumentPosition::FOURTH]);
459         return NapiAsyncWorkCallback(env, thisVar, cb).Schedule(PROCEDURE_CHECKSUM_NAME, cbExec, cbCompl).val_;
460     }
461 
462     return NapiValue::CreateUndefined(env).val_;
463 }
464 
Crc32Combine64(napi_env env,napi_callback_info info)465 napi_value ChecksumNExporter::Crc32Combine64(napi_env env, napi_callback_info info)
466 {
467     NapiFuncArg funcArg(env, info);
468     if (!funcArg.InitArgs(ArgumentCount::THREE, ArgumentCount::FOUR)) {
469         NapiBusinessError().ThrowErr(env, EINVAL);
470         return nullptr;
471     }
472 
473     /* To get entity */
474     auto checksumEntity = NapiClass::GetEntityOf<ChecksumEntity>(env, funcArg.GetThisVar());
475     if (!checksumEntity) {
476         NapiBusinessError().ThrowErr(env, EFAULT);
477         return nullptr;
478     }
479 
480     bool succ = false;
481     size_t len = 0;
482     uLong adler1 = 0U;
483     uLong adler2 = 0U;
484     tie(succ, adler1, adler2, len) = CommonFunc::GetAdler32CombineArg(env, funcArg);
485     if (!succ) {
486         return nullptr;
487     }
488 
489     auto arg = make_shared<AsyncChecksumArg>();
490     auto cbExec = [arg, adler1, adler2, len](napi_env env) -> NapiBusinessError {
491         if (!arg) {
492             return NapiBusinessError(EFAULT, true);
493         }
494         arg->adler = crc32_combine(static_cast<uLong>(adler1), static_cast<uLong>(adler2), static_cast<uInt>(len));
495         return NapiBusinessError(ERRNO_NOERR);
496     };
497 
498     auto cbCompl = [arg](napi_env env, NapiBusinessError err) -> NapiValue {
499         if (err) {
500             return {env, err.GetNapiErr(env)};
501         }
502         if (!arg) {
503             return {NapiValue::CreateUndefined(env)};
504         }
505         return {NapiValue::CreateInt64(env, arg->adler)};
506     };
507 
508     NapiValue thisVar(env, funcArg.GetThisVar());
509     if (funcArg.GetArgc() == ArgumentCount::THREE) {
510         return NapiAsyncWorkPromise(env, thisVar).Schedule(PROCEDURE_CHECKSUM_NAME, cbExec, cbCompl).val_;
511     } else {
512         NapiValue cb(env, funcArg[ArgumentPosition::FOURTH]);
513         return NapiAsyncWorkCallback(env, thisVar, cb).Schedule(PROCEDURE_CHECKSUM_NAME, cbExec, cbCompl).val_;
514     }
515 
516     return NapiValue::CreateUndefined(env).val_;
517 }
518 
GetCrcTable(napi_env env,napi_callback_info info)519 napi_value ChecksumNExporter::GetCrcTable(napi_env env, napi_callback_info info)
520 {
521     NapiFuncArg funcArg(env, info);
522     if (!funcArg.InitArgs(ArgumentCount::ZERO, ArgumentCount::ONE)) {
523         NapiBusinessError().ThrowErr(env, EINVAL);
524         return nullptr;
525     }
526 
527     size_t tableSize = 256;
528     auto arg = make_shared<AsyncChecksumArg>();
529     auto cbExec = [arg](napi_env env) -> NapiBusinessError {
530         if (!arg) {
531             return NapiBusinessError(EFAULT, true);
532         }
533         arg->crcTable = get_crc_table();
534         return NapiBusinessError(ERRNO_NOERR);
535     };
536 
537     auto cbCompl = [arg, tableSize](napi_env env, NapiBusinessError err) -> NapiValue {
538         if (err) {
539             return {env, err.GetNapiErr(env)};
540         }
541         if (!arg) {
542             return {NapiValue::CreateUndefined(env)};
543         }
544         std::vector<int64_t> crcVector(tableSize);
545         for (size_t i = 0; i < tableSize; ++i) {
546             crcVector[i] = static_cast<int64_t>(arg->crcTable[i]);
547         }
548         return {NapiValue::CreateInt64Array(env, crcVector)};
549     };
550 
551     NapiValue thisVar(env, funcArg.GetThisVar());
552     if (funcArg.GetArgc() == ArgumentCount::ZERO) {
553         return NapiAsyncWorkPromise(env, thisVar).Schedule(PROCEDURE_CHECKSUM_NAME, cbExec, cbCompl).val_;
554     } else {
555         NapiValue cb(env, funcArg[ArgumentPosition::FIRST]);
556         return NapiAsyncWorkCallback(env, thisVar, cb).Schedule(PROCEDURE_CHECKSUM_NAME, cbExec, cbCompl).val_;
557     }
558 
559     return NapiValue::CreateUndefined(env).val_;
560 }
561 
Crc64(napi_env env,napi_callback_info info)562 napi_value ChecksumNExporter::Crc64(napi_env env, napi_callback_info info)
563 {
564     NapiFuncArg funcArg(env, info);
565     if (!funcArg.InitArgs(ArgumentCount::TWO, ArgumentCount::THREE)) {
566         NapiBusinessError().ThrowErr(env, EINVAL);
567         return nullptr;
568     }
569 
570     bool succ = false;
571     void *buf = nullptr;
572     size_t len = 0;
573     uint64_t crc64 = 0U;
574     tie(succ, crc64, buf, len) = CommonFunc::GetCrc64Arg(env, funcArg);
575     if (!succ) {
576         return nullptr;
577     }
578 
579     auto arg = make_shared<AsyncChecksumArg>();
580     auto cbExec = [arg, crc64, buf, len](napi_env env) -> NapiBusinessError {
581         if (!arg) {
582             return NapiBusinessError(EFAULT, true);
583         }
584         arg->adler = ComputeCrc64(crc64, reinterpret_cast<char *>(buf), len);
585         return NapiBusinessError(ERRNO_NOERR);
586     };
587 
588     auto cbCompl = [arg](napi_env env, NapiBusinessError err) -> NapiValue {
589         if (err) {
590             return {env, err.GetNapiErr(env)};
591         }
592         if (!arg) {
593             return {NapiValue::CreateUndefined(env)};
594         }
595         return {NapiValue::CreateUint64(env, arg->adler)};
596     };
597 
598     NapiValue thisVar(env, funcArg.GetThisVar());
599     if (funcArg.GetArgc() == ArgumentCount::TWO) {
600         return NapiAsyncWorkPromise(env, thisVar).Schedule(PROCEDURE_CHECKSUM_NAME, cbExec, cbCompl).val_;
601     } else {
602         NapiValue cb(env, funcArg[ArgumentPosition::THIRD]);
603         return NapiAsyncWorkCallback(env, thisVar, cb).Schedule(PROCEDURE_CHECKSUM_NAME, cbExec, cbCompl).val_;
604     }
605 
606     return NapiValue::CreateUndefined(env).val_;
607 }
608 
GetCrc64Table(napi_env env,napi_callback_info info)609 napi_value ChecksumNExporter::GetCrc64Table(napi_env env, napi_callback_info info)
610 {
611     NapiFuncArg funcArg(env, info);
612     if (!funcArg.InitArgs(ArgumentCount::ZERO, ArgumentCount::ONE)) {
613         NapiBusinessError().ThrowErr(env, EINVAL);
614         return nullptr;
615     }
616 
617     size_t tableSize = 256;
618     auto arg = make_shared<AsyncChecksumArg>();
619     auto cbExec = [](napi_env env) -> NapiBusinessError {
620         return NapiBusinessError(ERRNO_NOERR);
621     };
622 
623     auto cbCompl = [arg, tableSize](napi_env env, NapiBusinessError err) -> NapiValue {
624         if (err) {
625             return {env, err.GetNapiErr(env)};
626         }
627         if (!arg) {
628             return {NapiValue::CreateUndefined(env)};
629         }
630         std::vector<uint64_t> crcVector(tableSize);
631         for (size_t i = 0; i < tableSize; ++i) {
632             crcVector[i] = static_cast<uint64_t>(CRC64_TABLE[i]);
633         }
634         return {NapiValue::CreateBigUint64Array(env, crcVector)};
635     };
636 
637     NapiValue thisVar(env, funcArg.GetThisVar());
638     if (funcArg.GetArgc() == ArgumentCount::ZERO) {
639         return NapiAsyncWorkPromise(env, thisVar).Schedule(PROCEDURE_CHECKSUM_NAME, cbExec, cbCompl).val_;
640     } else {
641         NapiValue cb(env, funcArg[ArgumentPosition::FIRST]);
642         return NapiAsyncWorkCallback(env, thisVar, cb).Schedule(PROCEDURE_CHECKSUM_NAME, cbExec, cbCompl).val_;
643     }
644 
645     return NapiValue::CreateUndefined(env).val_;
646 }
647 }  // namespace LIBZIP
648 }  // namespace AppExecFwk
649 }  // namespace OHOS