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