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 }