• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2024 Shenzhen Kaihong Digital Industry Development 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 "cJsonNapiH/cjsoncommon.h"
17 
18 constexpr uint8_t TYPE1 = 1;
19 constexpr uint8_t TYPE2 = 2;
20 
21 /*[NAPI_GEN]:错误处理,获取错误详细信息*/
getErrMessage(napi_status & status,napi_env & env,const napi_extended_error_info * & extended_error_info,const char * info,const char * tag)22 void getErrMessage(napi_status &status, napi_env &env, const napi_extended_error_info *&extended_error_info,
23     const char *info, const char *tag)
24 {
25     status = napi_get_last_error_info(env, &extended_error_info);
26     if (status == napi_ok && extended_error_info != NULL) {
27         const char *errorMessage =
28             extended_error_info->error_message != NULL ? extended_error_info->error_message : "Unknown error";
29         OH_LOG_Print(LOG_APP, LOG_ERROR, GLOBAL_RESMGR, tag, "errmsg %{public}s!, engine_err_code %{public}d!.",
30                      std::to_string(extended_error_info->engine_error_code).c_str(), extended_error_info->error_code);
31         std::string myInfo = info;
32         std::string res = "Failed to " + myInfo + " em = " + errorMessage +
33                           ", eec = " + std::to_string(extended_error_info->engine_error_code) +
34                           ", ec = " + std::to_string(extended_error_info->error_code);
35         napi_throw_error(env, NULL, res.c_str());
36     }
37 }
38 
39 /* 去除字符串中的换行符,便于查找打印, 公共方法
40  * str: 待去除\n的字符串
41  */
RemoveNewlines(std::string & str)42 void RemoveNewlines(std::string &str)
43 {
44     // 删除换行符、制表符和空格
45     str.erase(std::remove_if(str.begin(), str.end(), [](char c) { return c == '\n' || c == '\t' || c == ' '; }),
46               str.end());
47 }
48 
49 /* 检查JavaScript对象是否为空(不含自己的属性),公共方法
50  * env: 当前环境的句柄,代表当前的Node.js环境
51  * obj: 类型是napi_object
52  * tag: 日志打印标识符
53  */
IsEmptyObject(napi_env env,napi_value obj,const char * tag)54 bool IsEmptyObject(napi_env env, napi_value obj, const char *tag)
55 {
56     napi_status status;
57     const napi_extended_error_info *extended_error_info;
58     bool isEmpty = true; // 默认对象为空
59     // 首先检查传入的参数是否是对象
60     napi_valuetype valuetype;
61     status = napi_typeof(env, obj, &valuetype);
62     if (status != napi_ok) {
63         getErrMessage(status, env, extended_error_info, "IsEmptyObject: napi_typeof obj", tag);
64         return NULL;
65     }
66     if (valuetype == napi_object) {
67         // 创建一个属性名数组
68         uint32_t propertyCount;
69         napi_value propertyNames;
70         status = napi_get_property_names(env, obj, &propertyNames);
71         if (status != napi_ok) {
72             getErrMessage(status, env, extended_error_info, "IsEmptyObject: napi_get_property_names obj", tag);
73             return NULL;
74         }
75         // 计算属性的个数
76         status = napi_get_array_length(env, propertyNames, &propertyCount);
77         if (status != napi_ok) {
78             getErrMessage(status, env, extended_error_info, "IsEmptyObject: napi_get_array_length propertyNames", tag);
79             return NULL;
80         }
81         // 如果属性个数大于0,对象不为空
82         if (propertyCount > 0) {
83             isEmpty = false;
84         }
85     } else {
86         napi_throw_type_error(env, NULL, "Argument must be an object");
87         return NULL;
88     }
89 
90     return isEmpty;
91 }
92 
getNapiCjsonString(napi_env env,napi_value cjsonObj,const char * tag)93 char *getNapiCjsonString(napi_env env, napi_value cjsonObj, const char *tag)
94 {
95     napi_status status;
96     const napi_extended_error_info *extended_error_info;
97     // 获取string
98     napi_value napiPropStr;
99     status = napi_get_named_property(env, cjsonObj, "string", &napiPropStr);
100     if (status != napi_ok) {
101         getErrMessage(status, env, extended_error_info, "initCJSON_Object: napi_get_named_property 1", tag);
102         return NULL;
103     }
104     size_t strSize1 = 0;
105     status = napi_get_value_string_utf8(env, napiPropStr, NULL, 0, &strSize1);
106     if (status != napi_ok) {
107         getErrMessage(status, env, extended_error_info, "initCJSON_Object: get value string", tag);
108         return NULL;
109     }
110     char *objStrIn = new char[strSize1 + 1];
111     /* [NAPI_GEN]: 用于获取字符串*/
112     status = napi_get_value_string_utf8(env, napiPropStr, objStrIn, strSize1 + 1, &strSize1);
113     if (status != napi_ok) {
114         getErrMessage(status, env, extended_error_info, "initCJSON_Object: get value string", tag);
115         delete[] objStrIn;
116         return NULL;
117     }
118     return objStrIn;
119 }
120 
getNapiCjsonValuestring(napi_env env,napi_value cjsonObj,const char * tag)121 char *getNapiCjsonValuestring(napi_env env, napi_value cjsonObj, const char *tag)
122 {
123     napi_status status;
124     const napi_extended_error_info *extended_error_info;
125     // 获取valuestring
126     napi_value napiPropValueStr;
127     status = napi_get_named_property(env, cjsonObj, "valuestring", &napiPropValueStr);
128     if (status != napi_ok) {
129         getErrMessage(status, env, extended_error_info, "initCJSON_Object: napi_get_named_property", tag);
130         return NULL;
131     }
132     size_t strSize2 = 0;
133     status = napi_get_value_string_utf8(env, napiPropValueStr, NULL, 0, &strSize2);
134     if (status != napi_ok) {
135         getErrMessage(status, env, extended_error_info, "initCJSON_Object: get value string", tag);
136         return NULL;
137     }
138     char *objValueStrIn = new char[strSize2 + 1];
139     /* [NAPI_GEN]: 用于获取字符串*/
140     status = napi_get_value_string_utf8(env, napiPropValueStr, objValueStrIn, strSize2 + 1, &strSize2);
141     if (status != napi_ok) {
142         getErrMessage(status, env, extended_error_info, "initCJSON_Object: get value string", tag);
143         delete[] objValueStrIn;
144         return NULL;
145     }
146     return objValueStrIn;
147 }
148 
getNapiCjsonValuedouble(napi_env env,napi_value cjsonObj,const char * tag)149 double getNapiCjsonValuedouble(napi_env env, napi_value cjsonObj, const char *tag)
150 {
151     napi_status status;
152     const napi_extended_error_info *extended_error_info;
153     // 获取valuedouble 并加入obj
154     napi_value napiPropValueDouble;
155     status = napi_get_named_property(env, cjsonObj, "valuedouble", &napiPropValueDouble);
156     if (status != napi_ok) {
157         getErrMessage(status, env, extended_error_info, "initCJSON_Object: napi_get_named_property 2", tag);
158         return NULL;
159     }
160     double objValueDoubleIn = 0;
161     status = napi_get_value_double(env, napiPropValueDouble, &objValueDoubleIn);
162     if (status != napi_ok) {
163         getErrMessage(status, env, extended_error_info, "initCJSON_Object: napi_get_value_double", tag);
164         return NULL;
165     }
166     return objValueDoubleIn;
167 }
168 
getNapiCjsonType(napi_env env,napi_value cjsonObj,const char * tag)169 int getNapiCjsonType(napi_env env, napi_value cjsonObj, const char *tag)
170 {
171     napi_status status;
172     const napi_extended_error_info *extended_error_info;
173     // 获取cjson bool 并加入obj
174     napi_value napiPropValueBoolean;
175     status = napi_get_named_property(env, cjsonObj, "type", &napiPropValueBoolean);
176     if (status != napi_ok) {
177         getErrMessage(status, env, extended_error_info, "initCJSON_Object: napi_get_named_property 3", tag);
178         return NULL;
179     }
180 
181     int objValueTypeIn = 0;
182     status = napi_get_value_int32(env, napiPropValueBoolean, &objValueTypeIn);
183     if (status != napi_ok) {
184         getErrMessage(status, env, extended_error_info, "initCJSON_Object: napi_get_value_int32", tag);
185         return NULL;
186     }
187     return objValueTypeIn;
188 }
189 
getNapiCjsonChild(napi_env env,napi_value cjsonObj,cJSON * jsonObj,char * objStr,const char * tag)190 cJSON *getNapiCjsonChild(napi_env env, napi_value cjsonObj, cJSON *jsonObj, char *objStr, const char *tag)
191 {
192     napi_status status;
193     const napi_extended_error_info *extended_error_info;
194     // 遍历child
195     napi_value napiChildObj;
196     status = napi_get_named_property(env, cjsonObj, "child", &napiChildObj);
197     if (status != napi_ok) {
198         getErrMessage(status, env, extended_error_info, "initCJSON_Object: napi_get_named_property", tag);
199         return NULL;
200     }
201     if (objStr[0] != '\0') {
202         return jsonObj;
203     }
204     napi_valuetype valuetype;
205     status = napi_typeof(env, napiChildObj, &valuetype);
206     if (valuetype == napi_object) {
207         if (!IsEmptyObject(env, napiChildObj, tag)) {
208             jsonObj = initCJSON_Object(env, napiChildObj, jsonObj, tag);
209         }
210     }
211     return jsonObj;
212 }
213 
getNapiCjsonNext(napi_env env,napi_value cjsonObj,cJSON * jsonObj,const char * tag)214 cJSON *getNapiCjsonNext(napi_env env, napi_value cjsonObj, cJSON *jsonObj, const char *tag)
215 {
216     napi_status status;
217     const napi_extended_error_info *extended_error_info;
218     // 遍历next
219     napi_value napiNextObj;
220     status = napi_get_named_property(env, cjsonObj, "next", &napiNextObj);
221     if (status != napi_ok) {
222         getErrMessage(status, env, extended_error_info, "initCJSON_Object: napi_get_named_property", tag);
223         return NULL;
224     }
225     napi_valuetype valuetypeNext;
226     status = napi_typeof(env, napiNextObj, &valuetypeNext);
227     if (valuetypeNext == napi_object) {
228         if (!IsEmptyObject(env, napiNextObj, tag)) {
229             jsonObj = initCJSON_Object(env, napiNextObj, jsonObj, tag);
230         }
231     }
232     return jsonObj;
233 }
234 
getNapiCjsonPrev(napi_env env,napi_value cjsonObj,cJSON * jsonObj,const char * tag)235 cJSON *getNapiCjsonPrev(napi_env env, napi_value cjsonObj, cJSON *jsonObj, const char *tag)
236 {
237     napi_status status;
238     const napi_extended_error_info *extended_error_info;
239     // 遍历prev
240     napi_value napiPrevObj;
241     status = napi_get_named_property(env, cjsonObj, "prev", &napiPrevObj);
242     if (status != napi_ok) {
243         getErrMessage(status, env, extended_error_info, "initCJSON_Object: napi_get_named_property", tag);
244         return NULL;
245     }
246     napi_valuetype valuetypePrev;
247     status = napi_typeof(env, napiPrevObj, &valuetypePrev);
248     if (valuetypePrev == napi_object) {
249         if (!IsEmptyObject(env, napiPrevObj, tag)) {
250             jsonObj = initCJSON_Object(env, napiPrevObj, jsonObj, tag);
251         }
252     }
253     return jsonObj;
254 }
255 
getNapiCjsonChildArrObj(napi_env env,napi_value cjsonObj,cJSON * jsonObj,char * objStrIn,const char * tag)256 cJSON *getNapiCjsonChildArrObj(napi_env env, napi_value cjsonObj, cJSON *jsonObj, char *objStrIn, const char *tag)
257 {
258     napi_status status;
259     const napi_extended_error_info *extended_error_info;
260     // 遍历child 确认child是否是数组
261     napi_value napiChildObj;
262     status = napi_get_named_property(env, cjsonObj, "child", &napiChildObj);
263     if (status != napi_ok) {
264         getErrMessage(status, env, extended_error_info, "initCJSON_Object: napi_get_named_property", tag);
265         return NULL;
266     }
267     napi_valuetype valuetype;
268     status = napi_typeof(env, napiChildObj, &valuetype);
269     if (valuetype == napi_object) {
270         if (!IsEmptyObject(env, napiChildObj, tag)) {
271             char *objChildStrIn = getNapiCjsonString(env, napiChildObj, tag);
272             char *objChildValstrIn = getNapiCjsonValuestring(env, napiChildObj, tag);
273             if (objChildStrIn[0] == '\0' && objChildValstrIn[0] == '\0') {
274                 cJSON *jsonArray = cJSON_CreateArray();
275                 jsonArray = initCJSON_Array(env, napiChildObj, jsonArray, tag, false);
276                 cJSON_AddItemToObject(jsonObj, objStrIn, jsonArray);
277             }  else if (objChildStrIn[0] != '\0') {
278                 cJSON *jsonObject = cJSON_CreateObject();
279                 jsonObject = initCJSON_Object(env, napiChildObj, jsonObject, tag);
280                 cJSON_AddItemToObject(jsonObj, objStrIn, jsonObject);
281             }
282         }
283     }
284     return jsonObj;
285 }
286 
287 /* 在native初始化js传递的对象, 公共方法
288  * env: 当前环境的句柄,代表当前的Node.js环境
289  * cjsonObj: 从js传递的cJSON对象
290  * jsonObj: 待初始化的native层cJSON对象
291  * tag: 日志打印标识符
292  */
initCJSON_Object(napi_env env,napi_value cjsonObj,cJSON * jsonObj,const char * tag)293 cJSON *initCJSON_Object(napi_env env, napi_value cjsonObj, cJSON *jsonObj, const char *tag)
294 {
295     cJSON *jsonOut = nullptr;
296     char *objStrIn = getNapiCjsonString(env, cjsonObj, tag);
297     if (objStrIn != NULL && objStrIn[0] != '\0') {
298         char *objValueStrIn = getNapiCjsonValuestring(env, cjsonObj, tag);
299         if (objValueStrIn != NULL && objValueStrIn[0] != '\0') {
300             jsonOut = cJSON_AddStringToObject(jsonObj, objStrIn, objValueStrIn);
301         }
302         double objValueDoubleIn = getNapiCjsonValuedouble(env, cjsonObj, tag);
303         if (objValueDoubleIn != 0) {
304             jsonOut = cJSON_AddNumberToObject(jsonObj, objStrIn, objValueDoubleIn);
305         }
306         int objValueTypeIn = getNapiCjsonType(env, cjsonObj, tag);
307         if (objValueTypeIn == TYPE1) {
308             jsonOut = cJSON_AddFalseToObject(jsonObj, objStrIn);
309         } else if (objValueTypeIn == TYPE2) {
310             jsonOut = cJSON_AddTrueToObject(jsonObj, objStrIn);
311         }
312         // 判断 child是否是数组或者对象:例如{"test":[1,2,3]} 或者 {"test":{"name","john"}}
313         jsonObj = getNapiCjsonChildArrObj(env, cjsonObj, jsonObj, objStrIn, tag);
314     }
315 
316     // {"name":"Ann","age":18,"isStudent":true}类型字符串的解析
317     jsonObj = getNapiCjsonChild(env, cjsonObj, jsonObj, objStrIn, tag);
318     jsonObj = getNapiCjsonNext(env, cjsonObj, jsonObj, tag);
319     jsonObj = getNapiCjsonPrev(env, cjsonObj, jsonObj, tag);
320 
321     return jsonObj;
322 }
323 
getNapiCjsonArrayChild(napi_env env,napi_value cjsonObj,cJSON * jsonObj,const char * tag,bool flag)324 cJSON *getNapiCjsonArrayChild(napi_env env, napi_value cjsonObj, cJSON *jsonObj, const char *tag, bool flag)
325 {
326     napi_status status;
327     const napi_extended_error_info *extended_error_info;
328     // 遍历child
329     napi_value napiChildObj;
330     status = napi_get_named_property(env, cjsonObj, "child", &napiChildObj);
331     if (status != napi_ok) {
332         getErrMessage(status, env, extended_error_info, "initCJSON_Array: napi_get_named_property", tag);
333         return NULL;
334     }
335     napi_valuetype valuetype;
336     status = napi_typeof(env, napiChildObj, &valuetype);
337     if (valuetype == napi_object) {
338         if (!IsEmptyObject(env, napiChildObj, tag)) {
339             if (flag) {
340                 jsonObj = initCJSON_ArrayObj(env, napiChildObj, jsonObj, tag, true);
341             } else {
342                 jsonObj = initCJSON_Array(env, napiChildObj, jsonObj, tag, false);
343             }
344         }
345     }
346     return jsonObj;
347 }
348 
getNapiCjsonArrayNext(napi_env env,napi_value cjsonObj,cJSON * jsonObj,const char * tag,bool flag)349 cJSON *getNapiCjsonArrayNext(napi_env env, napi_value cjsonObj, cJSON *jsonObj, const char *tag, bool flag)
350 {
351     napi_status status;
352     const napi_extended_error_info *extended_error_info;
353     // 遍历next
354     napi_value napiNextObj;
355     status = napi_get_named_property(env, cjsonObj, "next", &napiNextObj);
356     if (status != napi_ok) {
357         getErrMessage(status, env, extended_error_info, "initCJSON_Array: napi_get_named_property", tag);
358         return NULL;
359     }
360     napi_valuetype valuetype;
361     status = napi_typeof(env, napiNextObj, &valuetype);
362     if (valuetype == napi_object) {
363         if (!IsEmptyObject(env, napiNextObj, tag)) {
364             if (flag) {
365                 jsonObj = initCJSON_ArrayObj(env, napiNextObj, jsonObj, tag, true);
366             } else {
367                 jsonObj = initCJSON_Array(env, napiNextObj, jsonObj, tag, false);
368             }
369         }
370     }
371     return jsonObj;
372 }
373 
getNapiCjsonArrayPrev(napi_env env,napi_value cjsonObj,cJSON * jsonObj,const char * tag,bool flag)374 cJSON *getNapiCjsonArrayPrev(napi_env env, napi_value cjsonObj, cJSON *jsonObj, const char *tag, bool flag)
375 {
376     napi_status status;
377     const napi_extended_error_info *extended_error_info;
378     // 遍历prev
379     napi_value napiPrevObj;
380     status = napi_get_named_property(env, cjsonObj, "prev", &napiPrevObj);
381     if (status != napi_ok) {
382         getErrMessage(status, env, extended_error_info, "initCJSON_Array: napi_get_named_property", tag);
383         return NULL;
384     }
385     napi_valuetype valuetype;
386     status = napi_typeof(env, napiPrevObj, &valuetype);
387     if (valuetype == napi_object) {
388         if (!IsEmptyObject(env, napiPrevObj, tag)) {
389             if (flag) {
390                 jsonObj = initCJSON_ArrayObj(env, napiPrevObj, jsonObj, tag, true);
391             } else {
392                 jsonObj = initCJSON_Array(env, napiPrevObj, jsonObj, tag, false);
393             }
394         }
395     }
396     return jsonObj;
397 }
398 
399 /* 在native初始化js传递的对象, 公共方法
400  * env: 当前环境的句柄,代表当前的Node.js环境
401  * cjsonObj: 从js传递的cJSON对象,该对象表示一个基本类型的数组,如[9,-2,7]
402  * jsonObj: 待初始化的native层cJSON对象
403  * tag: 日志打印标识符
404  * flag: true表示判断是普通array,如:[2,-3,6];false表示判断数组元素是否是对象,如:[{"name":"ann"},{"name":"john"}]
405  * return cJSON: 返回c++ cJSON对象
406  */
initCJSON_Array(napi_env env,napi_value cjsonObj,cJSON * jsonObj,const char * tag,bool flag)407 cJSON *initCJSON_Array(napi_env env, napi_value cjsonObj, cJSON *jsonObj, const char *tag, bool flag)
408 {
409     char *objStrIn = getNapiCjsonString(env, cjsonObj, tag);
410     if (objStrIn[0] == '\0') {
411         int objValueTypeIn = getNapiCjsonType(env, cjsonObj, tag);
412         if (objValueTypeIn != cJSON_NULL && objValueTypeIn != cJSON_Invalid) {
413             double objValueDoubleIn = getNapiCjsonValuedouble(env, cjsonObj, tag);
414             // 打印出来objValueDoubleIn
415             if (objValueDoubleIn != 0) {
416                 cJSON_AddItemToArray(jsonObj, cJSON_CreateNumber(objValueDoubleIn));
417             }
418         }
419     }
420 
421     jsonObj = getNapiCjsonArrayChild(env, cjsonObj, jsonObj, tag, flag);
422     jsonObj = getNapiCjsonArrayNext(env, cjsonObj, jsonObj, tag, flag);
423     jsonObj = getNapiCjsonArrayPrev(env, cjsonObj, jsonObj, tag, flag);
424 
425     return jsonObj;
426 }
427 
428 /* 在native初始化js传递的对象, 公共方法
429  * env: 当前环境的句柄,代表当前的Node.js环境
430  * cjsonObj: 从js传递的cJSON对象,该对象表示一个数组,如:[{"name":"ann"},{"name":"john"}]
431  * jsonObj: 待初始化的native层cJSON对象
432  * tag: 日志打印标识符
433  * flag: true表示判断是普通array,如:[2,-3,6];false表示判断数组元素是否是对象,如:[{"name":"ann"},{"name":"john"}]
434  * return cJSON: 返回c++ cJSON对象
435  */
initCJSON_ArrayObj(napi_env env,napi_value cjsonObj,cJSON * jsonObj,const char * tag,bool flag)436 cJSON *initCJSON_ArrayObj(napi_env env, napi_value cjsonObj, cJSON *jsonObj, const char *tag, bool flag)
437 {
438     char *objStrIn = getNapiCjsonString(env, cjsonObj, tag);
439     if (objStrIn[0] != '\0') {
440         cJSON *arrObj = cJSON_CreateObject();
441         arrObj = initCJSON_Object(env, cjsonObj, arrObj, tag);
442         char *rootString1 = cJSON_Print(arrObj);
443         bool isObjNull = false;
444         if (rootString1 != NULL) {
445             // 需要去掉字符串中的\n 这样方便查找打印出的字符串
446             std::string printRootStr = rootString1;
447             RemoveNewlines(printRootStr);
448             if (printRootStr == "{}") {
449                 isObjNull = true;
450             }
451         }
452         if (!isObjNull) {
453             cJSON *objItem = cJSON_CreateObject();
454             cJSON_AddItemToArray(jsonObj, objItem);
455             objItem = initCJSON_Object(env, cjsonObj, objItem, tag);
456             char *rootString2 = cJSON_Print(jsonObj);
457             if (rootString2 != NULL) {
458                 // 需要去掉字符串中的\n 这样方便查找打印出的字符串
459                 std::string printRootStr = rootString2;
460                 RemoveNewlines(printRootStr);
461             }
462             return jsonObj;
463         }
464     }
465 
466     jsonObj = getNapiCjsonArrayChild(env, cjsonObj, jsonObj, tag, flag);
467     jsonObj = getNapiCjsonArrayNext(env, cjsonObj, jsonObj, tag, flag);
468     jsonObj = getNapiCjsonArrayPrev(env, cjsonObj, jsonObj, tag, flag);
469 
470     return jsonObj;
471 }
472 
473 /* 判断是单纯对象还是arrObj或objArr
474  * env: 当前环境的句柄,代表当前的Node.js环境
475  * cjsonObj: 从js传递的cJSON对象
476  * tag: 日志打印标识
477  * return 布尔值:若对象是array object或者object array返回true,如[{"name":"john"}]或{"testArr":[9,8,7]}
478  */
isArrObject(napi_env env,napi_value cjsonObj,const char * tag)479 bool isArrObject(napi_env env, napi_value cjsonObj, const char *tag)
480 {
481     // 判断 root->child-string有没有值,有值则认为是普通object,没有值则认为是arrayObject
482     napi_status status;
483     const napi_extended_error_info *extended_error_info;
484     // 遍历child
485     napi_value napiChildObj;
486     status = napi_get_named_property(env, cjsonObj, "child", &napiChildObj);
487     if (status != napi_ok) {
488         getErrMessage(status, env, extended_error_info, "initCJSON_Array: napi_get_named_property", tag);
489         return NULL;
490     }
491     napi_valuetype valuetype;
492     status = napi_typeof(env, napiChildObj, &valuetype);
493     if (valuetype == napi_object) {
494         if (!IsEmptyObject(env, napiChildObj, tag)) {
495             char *objStrIn = getNapiCjsonString(env, napiChildObj, tag);
496             if (objStrIn[0] == '\0') {
497                 return true;
498             } else {
499                 bool isTrue = isArrObject(env, napiChildObj, tag);
500                 return isTrue;
501             }
502         } else {
503             return false;
504         }
505     }
506     return false;
507 }