• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2023 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #include "napi/native_api.h"
17 #include <cerrno>
18 #include <cstdio>
19 #include <cstdlib>
20 #include <cstring>
21 #include <ctime>
22 #include <js_native_api.h>
23 #include <malloc.h>
24 #include <node_api.h>
25 #include <search.h>
26 #include <unistd.h>
27 
28 #define PARAM_0 0
29 #define PARAM_5 5
30 #define PARAM_27 27
31 #define PARAM_1 1
32 #define PARAM_2 2
33 #define PARAM_10 10
34 #define PARAM_3 3
35 #define PARAM_24 24
36 #define PARAM_30 30
37 #define PARAM_22 22
38 #define PARAM_26 26
39 #define PARAM_0xff 0xff
40 #define PARAM_UNNORMAL (-1)
41 #define ERRON_0 0
42 #define TWICE 12
43 #define ARRAY_SIZE (10)
44 #define FAIL (-1)
45 #define NOERR 0
46 #define VALUE_ONE 1
47 #define VALUE_TWO 1
48 #define BUFFERSIZE 128
49 #define LOOPNUM 12
50 static void *g_root = nullptr;
51 
Compare(const void * pa,const void * pb)52 static int Compare(const void *pa, const void *pb)
53 {
54     if (*static_cast<const int *>(pa) < *static_cast<const int *>(pb))
55         return PARAM_UNNORMAL;
56     if (*static_cast<const int *>(pa) > *static_cast<const int *>(pb))
57         return VALUE_ONE;
58     return NOERR;
59 }
60 
action(const void * nodep,VISIT which,int depth)61 static void action(const void *nodep, VISIT which, int depth)
62 {
63     int *datap = nullptr;
64 
65     switch (which) {
66     case preorder:
67         break;
68     case postorder:
69         datap = *(int **)nodep;
70         printf("%6d\n", *datap);
71         break;
72     case endorder:
73         break;
74     case leaf:
75         datap = *(int **)nodep;
76         printf("%6d\n", *datap);
77         break;
78     }
79 }
80 
Tdestroy(napi_env env,napi_callback_info info)81 static napi_value Tdestroy(napi_env env, napi_callback_info info)
82 {
83     void *rootParam = nullptr;
84     napi_value result = nullptr;
85     errno = ERRON_0;
86     tdestroy(rootParam, free);
87     napi_create_int32(env, errno, &result);
88     return result;
89 }
90 
Tdelete(napi_env env,napi_callback_info info)91 static napi_value Tdelete(napi_env env, napi_callback_info info)
92 {
93     errno = ERRON_0;
94     tdelete(g_root, nullptr, nullptr);
95     napi_value result = nullptr;
96     napi_create_int32(env, errno, &result);
97     return result;
98 }
99 
Tfind(napi_env env,napi_callback_info info)100 static napi_value Tfind(napi_env env, napi_callback_info info)
101 {
102     errno = ERRON_0;
103     tfind(g_root, nullptr, nullptr);
104     napi_value result = nullptr;
105     napi_create_int32(env, errno, &result);
106     return result;
107 }
108 
Hcreate(napi_env env,napi_callback_info info)109 static napi_value Hcreate(napi_env env, napi_callback_info info)
110 {
111     int ret = PARAM_0;
112     ret = hcreate(BUFSIZ);
113     hdestroy();
114     napi_value result = nullptr;
115     if (ret == NOERR) {
116         napi_create_int32(env, FAIL, &result);
117     } else {
118         napi_create_int32(env, NOERR, &result);
119     }
120     return result;
121 }
122 
HcreateR(napi_env env,napi_callback_info info)123 static napi_value HcreateR(napi_env env, napi_callback_info info)
124 {
125     int ret = PARAM_0;
126     struct hsearch_data h_data = {PARAM_0};
127     hcreate_r(BUFSIZ, &h_data);
128     hdestroy_r(&h_data);
129     napi_value result = nullptr;
130     if (ret == NOERR) {
131         napi_create_int32(env, FAIL, &result);
132     } else {
133         napi_create_int32(env, NOERR, &result);
134     }
135     return result;
136 }
137 
Hdestroy(napi_env env,napi_callback_info info)138 static napi_value Hdestroy(napi_env env, napi_callback_info info)
139 {
140     int ret = PARAM_0;
141     ret = hcreate(BUFSIZ);
142     hdestroy();
143     ret = hcreate(BUFSIZ);
144     hdestroy();
145     napi_value result = nullptr;
146     if (ret == NOERR) {
147         napi_create_int32(env, FAIL, &result);
148     } else {
149         napi_create_int32(env, NOERR, &result);
150     }
151     return result;
152 }
153 
HdestroyR(napi_env env,napi_callback_info info)154 static napi_value HdestroyR(napi_env env, napi_callback_info info)
155 {
156     int ret = PARAM_0;
157     struct hsearch_data h_data = {PARAM_0};
158     memset(&h_data, PARAM_0, sizeof(struct hsearch_data));
159     hcreate_r(BUFSIZ, &h_data);
160     hdestroy_r(&h_data);
161     memset(&h_data, PARAM_0, sizeof(struct hsearch_data));
162     ret = hcreate_r(BUFSIZ, &h_data);
163     hdestroy_r(&h_data);
164     napi_value result = nullptr;
165     if (ret == PARAM_0) {
166         napi_create_int32(env, FAIL, &result);
167     } else {
168         napi_create_int32(env, NOERR, &result);
169     }
170     return result;
171 }
172 
173 static char data[][30] = {"alpha",  "bravo", "charlie", "delta",  "echo",     "foxtrot", "golf",   "hotel",  "india",
174                           "juliet", "kilo",  "lima",    "mike",   "november", "oscar",   "papa",   "quebec", "romeo",
175                           "sierra", "tango", "uniform", "victor", "whisky",   "x-ray",   "yankee", "zulu"};
176 
Hsearch(napi_env env,napi_callback_info info)177 static napi_value Hsearch(napi_env env, napi_callback_info info)
178 {
179     napi_value result = nullptr;
180     ENTRY e, *ep;
181     int i;
182 
183     hcreate(PARAM_30);
184 
185     for (i = PARAM_0; i < PARAM_24; i++) {
186         e.key = data[i];
187         e.data = (void *)i;
188         ep = hsearch(e, ENTER);
189         if (ep == nullptr) {
190             napi_create_int32(env, FAIL, &result);
191             return result;
192         }
193     }
194 
195     for (i = PARAM_22; i < PARAM_26; i++) {
196         e.key = data[i];
197         ep = hsearch(e, FIND);
198     }
199     hdestroy();
200     napi_create_int32(env, NOERR, &result);
201     return result;
202 }
203 
HsearchR(napi_env env,napi_callback_info info)204 static napi_value HsearchR(napi_env env, napi_callback_info info)
205 {
206     napi_value result = nullptr;
207     struct hsearch_data *htab = (struct hsearch_data *)calloc(VALUE_ONE, sizeof(struct hsearch_data));
208     if (!htab) {
209         printf("calloc fail\n");
210         exit(NOERR);
211     }
212     if (hcreate_r(PARAM_10, htab) == PARAM_0) {
213         printf("hcreat_r fail\n");
214         exit(NOERR);
215     }
216     char keys[][8] = {"key1", "key2", "key3"};
217     char dataVal[][8] = {"yasuo", "kitty", "ruiwen"};
218     int i;
219     for (i = PARAM_0; i < PARAM_3; i++) {
220         ENTRY e, *ep;
221         e.key = keys[i];
222         e.data = (void *)dataVal[i];
223         hsearch_r(e, ENTER, &ep, htab);
224     }
225     for (i = PARAM_0; i < PARAM_3; i++) {
226         ENTRY e2, *ep2;
227         e2.key = keys[i];
228         hsearch_r(e2, FIND, &ep2, htab);
229         if (ep2 != nullptr) {
230             napi_create_int32(env, NOERR, &result);
231         } else {
232             napi_create_int32(env, FAIL, &result);
233         }
234     }
235     hdestroy_r(htab);
236     if (htab) {
237         free(htab);
238     }
239     napi_create_int32(env, FAIL, &result);
240     return result;
241 }
242 
243 struct Q {
244     struct Q *n;
245     struct Q *p;
246     int i;
247 };
248 
Insque(napi_env env,napi_callback_info info)249 static napi_value Insque(napi_env env, napi_callback_info info)
250 {
251     struct Q elem = {PARAM_0};
252     insque(&elem, nullptr);
253     napi_value result = nullptr;
254     if (elem.n == nullptr && elem.p == nullptr) {
255         napi_create_int32(env, NOERR, &result);
256     } else {
257         napi_create_int32(env, FAIL, &result);
258     }
259     return result;
260 }
261 
262 typedef int (*fc)(const void *, const void *);
263 
LSearch(napi_env env,napi_callback_info info)264 static napi_value LSearch(napi_env env, napi_callback_info info)
265 {
266     int arr[5] = {27, 14, 29, 68, 55};
267     size_t n = PARAM_5;
268     int key = PARAM_27;
269     fc f = Compare;
270     int *ret = static_cast<int*>(lsearch(&key, arr, &n, sizeof(int), f));
271     napi_value result = nullptr;
272     if (ret) {
273         napi_create_int32(env, NOERR, &result);
274     } else {
275         napi_create_int32(env, FAIL, &result);
276     }
277     return result;
278 }
279 
Lfind(napi_env env,napi_callback_info info)280 static napi_value Lfind(napi_env env, napi_callback_info info)
281 {
282     size_t argc = PARAM_2;
283     napi_value args[2] = {nullptr};
284     napi_get_cb_info(env, info, &argc, args, nullptr, nullptr);
285     int array[3];
286     size_t nlength;
287     int key = PARAM_0;
288     void *ret = nullptr;
289     napi_get_value_int32(env, args[0], array);
290     napi_get_value_int32(env, args[0], array + VALUE_ONE);
291     napi_get_value_int32(env, args[0], array + VALUE_TWO);
292     napi_get_value_int32(env, args[0], &key);
293     ret = lfind(&key, array, &nlength, sizeof(int), Compare);
294     napi_value result = nullptr;
295     if (ret == nullptr) {
296         napi_create_int32(env, FAIL, &result);
297     } else {
298         napi_create_int32(env, NOERR, &result);
299     }
300     return result;
301 }
302 
Remque(napi_env env,napi_callback_info info)303 static napi_value Remque(napi_env env, napi_callback_info info)
304 {
305     errno = NOERR;
306     struct Q *elem = (struct Q *)malloc(sizeof(struct Q));
307     insque(elem, nullptr);
308     remque(elem);
309     napi_value result = nullptr;
310     if (errno == NOERR) {
311         napi_create_int32(env, NOERR, &result);
312     } else {
313         napi_create_int32(env, FAIL, &result);
314     }
315     return result;
316 }
317 
318 struct stu {
319     int stu_no;
320     char name[BUFFERSIZE];
321 };
322 
323 typedef struct stu stu_t;
CompareStu(const void * pa,const void * pb)324 int CompareStu(const void *pa, const void *pb) { return ((stu_t *)pa)->stu_no - ((stu_t *)pb)->stu_no; }
325 
Tsearch(napi_env env,napi_callback_info info)326 static napi_value Tsearch(napi_env env, napi_callback_info info)
327 {
328     void *rootVal = nullptr;
329     stu_t stuSturct;
330     sprintf(stuSturct.name, "shanghai_%d", stuSturct.stu_no);
331     stu_t **rtp = (stu_t **)tsearch(&stuSturct, &rootVal, CompareStu);
332     napi_value result = nullptr;
333     if (rtp != nullptr) {
334         napi_create_int32(env, NOERR, &result);
335     } else {
336         napi_create_int32(env, FAIL, &result);
337     }
338 
339     return result;
340 }
341 
Twalk(napi_env env,napi_callback_info info)342 static napi_value Twalk(napi_env env, napi_callback_info info)
343 {
344     int i = PARAM_0, *ptr = nullptr;
345     void *val = nullptr;
346     void *rootVal = nullptr;
347     srand(time(nullptr));
348     for (i = PARAM_0; i < LOOPNUM; i++) {
349         ptr = static_cast<int*>(malloc(sizeof(int)));
350         *ptr = rand() & PARAM_0xff;
351         val = tsearch((void *)ptr, &rootVal, Compare);
352         if (val == nullptr)
353             exit(EXIT_FAILURE);
354         else if ((*(int **)val) != ptr)
355             free(ptr);
356     }
357     twalk(rootVal, action);
358     tdestroy(rootVal, free);
359     napi_value result = nullptr;
360     if (rootVal != nullptr) {
361         napi_create_int32(env, NOERR, &result);
362     } else {
363         napi_create_int32(env, FAIL, &result);
364     }
365     return result;
366 }
367 
368 EXTERN_C_START
Init(napi_env env,napi_value exports)369 static napi_value Init(napi_env env, napi_value exports)
370 {
371     napi_property_descriptor desc[] = {
372         {"tdestroy", nullptr, Tdestroy, nullptr, nullptr, nullptr, napi_default, nullptr},
373         {"tdelete", nullptr, Tdelete, nullptr, nullptr, nullptr, napi_default, nullptr},
374         {"tfind", nullptr, Tfind, nullptr, nullptr, nullptr, napi_default, nullptr},
375         {"hcreate", nullptr, Hcreate, nullptr, nullptr, nullptr, napi_default, nullptr},
376         {"hcreateR", nullptr, HcreateR, nullptr, nullptr, nullptr, napi_default, nullptr},
377         {"hdestroy", nullptr, Hdestroy, nullptr, nullptr, nullptr, napi_default, nullptr},
378         {"hdestroyR", nullptr, HdestroyR, nullptr, nullptr, nullptr, napi_default, nullptr},
379         {"hsearch", nullptr, Hsearch, nullptr, nullptr, nullptr, napi_default, nullptr},
380         {"hsearchR", nullptr, HsearchR, nullptr, nullptr, nullptr, napi_default, nullptr},
381         {"insque", nullptr, Insque, nullptr, nullptr, nullptr, napi_default, nullptr},
382         {"lSearch", nullptr, LSearch, nullptr, nullptr, nullptr, napi_default, nullptr},
383         {"lfind", nullptr, Lfind, nullptr, nullptr, nullptr, napi_default, nullptr},
384         {"remque", nullptr, Remque, nullptr, nullptr, nullptr, napi_default, nullptr},
385         {"tsearch", nullptr, Tsearch, nullptr, nullptr, nullptr, napi_default, nullptr},
386         {"twalk", nullptr, Twalk, nullptr, nullptr, nullptr, napi_default, nullptr},
387     };
388     napi_define_properties(env, exports, sizeof(desc) / sizeof(desc[0]), desc);
389     return exports;
390 }
391 
392 EXTERN_C_END
393 
394 static napi_module demoModule = {
395     .nm_version = 1,
396     .nm_flags = 0,
397     .nm_filename = nullptr,
398     .nm_register_func = Init,
399     .nm_modname = "search",
400     .nm_priv = ((void *)0),
401     .reserved = {0},
402 };
403 
RegisterEntryModule(void)404 extern "C" __attribute__((constructor)) void RegisterEntryModule(void) { napi_module_register(&demoModule); }
405