1 /* 2 * Copyright (c) 2022 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 "js_xml.h" 17 #include "napi/native_api.h" 18 #include "napi/native_node_api.h" 19 20 extern const char _binary_js_xml_js_start[]; 21 extern const char _binary_js_xml_js_end[]; 22 extern const char _binary_xml_abc_start[]; 23 extern const char _binary_xml_abc_end[]; 24 25 namespace OHOS::xml { XmlSerializerConstructor(napi_env env,napi_callback_info info)26 static napi_value XmlSerializerConstructor(napi_env env, napi_callback_info info) 27 { 28 napi_value thisVar = nullptr; 29 void *data = nullptr; 30 size_t argc = 0; 31 napi_value args[2] = { 0 }; // 2:The number of parameters is 2 32 XmlSerializer *object = nullptr; 33 size_t iLength = 0; 34 size_t offPos = 0; 35 napi_value arraybuffer = nullptr; 36 NAPI_CALL(env, napi_get_cb_info(env, info, &argc, nullptr, &thisVar, &data)); 37 NAPI_ASSERT(env, argc == 1 || argc == 2, "Wrong number of arguments"); // 2: number of args 38 NAPI_CALL(env, napi_get_cb_info(env, info, &argc, args, &thisVar, &data)); 39 if (args[0] == nullptr) { 40 NAPI_CALL(env, napi_throw_error(env, "", "parameter is empty")); 41 return nullptr; 42 } else { 43 bool bFlag = false; 44 napi_is_arraybuffer(env, args[0], &bFlag); 45 if (bFlag) { 46 napi_get_arraybuffer_info(env, args[0], &data, &iLength); 47 } 48 napi_is_dataview(env, args[0], &bFlag); 49 if (bFlag) { 50 napi_get_dataview_info(env, args[0], &iLength, &data, &arraybuffer, &offPos); 51 } 52 } 53 if (argc == 1) { 54 object = new XmlSerializer(reinterpret_cast<char*>(data), iLength); 55 } else if (argc == 2) { // 2:When the input parameter is set to 2 56 std::string encoding = ""; 57 napi_valuetype valuetype; 58 NAPI_CALL(env, napi_typeof(env, args[1], &valuetype)); 59 NAPI_ASSERT(env, valuetype == napi_string, "Wrong argument typr. String expected."); 60 napi_status status = napi_ok; 61 status = XmlSerializer::DealNapiStrValue(env, args[1], encoding); 62 if (status == napi_ok) { 63 object = new XmlSerializer(reinterpret_cast<char*>(data), iLength, encoding); 64 } 65 } 66 napi_wrap( 67 env, thisVar, object, 68 [](napi_env environment, void *data, void *hint) { 69 auto obj = reinterpret_cast<XmlSerializer*>(data); 70 if (obj != nullptr) { 71 delete obj; 72 } 73 }, 74 nullptr, nullptr); 75 return thisVar; 76 } 77 XmlPullParserConstructor(napi_env env,napi_callback_info info)78 static napi_value XmlPullParserConstructor(napi_env env, napi_callback_info info) 79 { 80 napi_value thisVar = nullptr; 81 void *data = nullptr; 82 size_t argc = 0; 83 napi_value args[2] = { 0 }; // 2:two args 84 XmlPullParser *object = nullptr; 85 NAPI_CALL(env, napi_get_cb_info(env, info, &argc, nullptr, &thisVar, &data)); 86 NAPI_ASSERT(env, argc == 1 || argc == 2, "Wrong number of arguments"); // 2:two args 87 NAPI_CALL(env, napi_get_cb_info(env, info, &argc, args, &thisVar, &data)); 88 napi_valuetype valuetype = napi_null; 89 NAPI_CALL(env, napi_typeof(env, args[0], &valuetype)); 90 NAPI_ASSERT(env, valuetype == napi_object, "Wrong argument typr. Object(DataView or ArrayBuffer) expected."); 91 bool bFlag = false; 92 size_t len = 0; 93 size_t offPos = 0; 94 napi_value arraybuffer = nullptr; 95 NAPI_ASSERT(env, args[0] != nullptr, "Wrong argument value. (not nullptr expected)."); 96 napi_is_arraybuffer(env, args[0], &bFlag); 97 if (bFlag) { 98 napi_get_arraybuffer_info(env, args[0], &data, &len); 99 } 100 napi_is_dataview(env, args[0], &bFlag); 101 if (bFlag) { 102 napi_get_dataview_info(env, args[0], &len, &data, &arraybuffer, &offPos); 103 } 104 if (data) { 105 std::string strEnd(reinterpret_cast<char*>(data), len); 106 strEnd = strEnd.substr(0, std::strlen(strEnd.c_str())); 107 if (argc == 1) { 108 object = new XmlPullParser(strEnd, "utf-8"); 109 } else if (argc == 2) { // 2:When the input parameter is set to 2 110 NAPI_CALL(env, napi_typeof(env, args[1], &valuetype)); 111 NAPI_ASSERT(env, valuetype == napi_string, "Wrong argument typr. String expected."); 112 std::string strEncoding = ""; 113 XmlSerializer::DealNapiStrValue(env, args[1], strEncoding); 114 object = new XmlPullParser(strEnd, strEncoding); 115 } 116 } 117 napi_wrap( 118 env, thisVar, object, 119 [](napi_env env, void *data, void *hint) { 120 auto obj = reinterpret_cast<XmlPullParser*>(data); 121 if (obj != nullptr) { 122 delete obj; 123 } 124 }, 125 nullptr, nullptr); 126 return thisVar; 127 } 128 SetAttributes(napi_env env,napi_callback_info info)129 static napi_value SetAttributes(napi_env env, napi_callback_info info) 130 { 131 napi_value thisVar = nullptr; 132 size_t argc = 0; 133 napi_value args[2] = { 0 }; // 2:two args 134 NAPI_CALL(env, napi_get_cb_info(env, info, &argc, nullptr, &thisVar, nullptr)); 135 NAPI_CALL(env, napi_get_cb_info(env, info, &argc, args, &thisVar, nullptr)); 136 NAPI_ASSERT(env, argc == 2, "Wrong number of arguments"); // 2: number of args 137 napi_valuetype valuetype = napi_null; 138 NAPI_ASSERT(env, args[0] != nullptr, "Parameter is empty."); 139 NAPI_ASSERT(env, args[1] != nullptr, "Parameter is empty."); 140 NAPI_CALL(env, napi_typeof(env, args[0], &valuetype)); 141 NAPI_ASSERT(env, valuetype == napi_string, "Wrong argument typr. Object expected."); 142 NAPI_CALL(env, napi_typeof(env, args[1], &valuetype)); 143 NAPI_ASSERT(env, valuetype == napi_string, "Wrong argument typr. Object expected."); 144 XmlSerializer *object = nullptr; 145 NAPI_CALL(env, napi_unwrap(env, thisVar, reinterpret_cast<void**>(&object))); 146 std::string name; 147 std::string value; 148 XmlSerializer::DealNapiStrValue(env, args[0], name); 149 XmlSerializer::DealNapiStrValue(env, args[1], value); 150 object->SetAttributes(name, value); 151 napi_value result = nullptr; 152 NAPI_CALL(env, napi_get_undefined(env, &result)); 153 return result; 154 } 155 AddEmptyElement(napi_env env,napi_callback_info info)156 static napi_value AddEmptyElement(napi_env env, napi_callback_info info) 157 { 158 napi_value thisVar = nullptr; 159 size_t argc = 1; 160 napi_value args[1] = { 0 }; 161 NAPI_CALL(env, napi_get_cb_info(env, info, &argc, args, &thisVar, nullptr)); 162 NAPI_ASSERT(env, argc == 1, "Wrong number of arguments(Over)"); 163 if (args[0] == nullptr) { 164 NAPI_CALL(env, napi_throw_error(env, "", "parameter is empty")); 165 return nullptr; 166 } else { 167 napi_valuetype valuetype; 168 NAPI_CALL(env, napi_typeof(env, args[0], &valuetype)); 169 NAPI_ASSERT(env, valuetype == napi_string, "Wrong argument typr. String expected."); 170 XmlSerializer *object = nullptr; 171 NAPI_CALL(env, napi_unwrap(env, thisVar, reinterpret_cast<void**>(&object))); 172 std::string name; 173 object->DealNapiStrValue(env, args[0], name); 174 object->AddEmptyElement(name); 175 } 176 napi_value result = nullptr; 177 NAPI_CALL(env, napi_get_undefined(env, &result)); 178 return result; 179 } 180 SetDeclaration(napi_env env,napi_callback_info info)181 static napi_value SetDeclaration(napi_env env, napi_callback_info info) 182 { 183 napi_value thisVar = nullptr; 184 NAPI_CALL(env, napi_get_cb_info(env, info, nullptr, nullptr, &thisVar, nullptr)); 185 XmlSerializer *object = nullptr; 186 NAPI_CALL(env, napi_unwrap(env, thisVar, reinterpret_cast<void**>(&object))); 187 object->SetDeclaration(); 188 napi_value result = nullptr; 189 NAPI_CALL(env, napi_get_undefined(env, &result)); 190 return result; 191 } 192 StartElement(napi_env env,napi_callback_info info)193 static napi_value StartElement(napi_env env, napi_callback_info info) 194 { 195 size_t argc = 1; 196 napi_value args[1] = { 0 }; 197 napi_value thisVar = nullptr; 198 NAPI_CALL(env, napi_get_cb_info(env, info, &argc, nullptr, &thisVar, nullptr)); 199 NAPI_ASSERT(env, argc == 1, "Wrong number of arguments"); 200 NAPI_CALL(env, napi_get_cb_info(env, info, &argc, args, &thisVar, nullptr)); 201 NAPI_ASSERT(env, args[0] != nullptr, "Parameter is empty."); 202 XmlSerializer *object = nullptr; 203 NAPI_CALL(env, napi_unwrap(env, thisVar, reinterpret_cast<void**>(&object))); 204 std::string name; 205 object->DealNapiStrValue(env, args[0], name); 206 object->StartElement(name); 207 napi_value result = nullptr; 208 NAPI_CALL(env, napi_get_undefined(env, &result)); 209 return result; 210 } 211 EndElement(napi_env env,napi_callback_info info)212 static napi_value EndElement(napi_env env, napi_callback_info info) 213 { 214 napi_value thisVar = nullptr; 215 NAPI_CALL(env, napi_get_cb_info(env, info, nullptr, nullptr, &thisVar, nullptr)); 216 XmlSerializer *object = nullptr; 217 NAPI_CALL(env, napi_unwrap(env, thisVar, reinterpret_cast<void**>(&object))); 218 object->EndElement(); 219 napi_value result = nullptr; 220 NAPI_CALL(env, napi_get_undefined(env, &result)); 221 return result; 222 } 223 SetNamespace(napi_env env,napi_callback_info info)224 static napi_value SetNamespace(napi_env env, napi_callback_info info) 225 { 226 napi_value thisVar = nullptr; 227 size_t argc = 0; 228 napi_value args[2] = { 0 }; // 2:two args 229 NAPI_CALL(env, napi_get_cb_info(env, info, &argc, nullptr, &thisVar, nullptr)); 230 NAPI_CALL(env, napi_get_cb_info(env, info, &argc, args, &thisVar, nullptr)); 231 NAPI_ASSERT(env, argc == 2, "Wrong number of arguments"); // 2:two args 232 napi_valuetype valuetype = napi_null; 233 NAPI_ASSERT(env, args[0] != nullptr, "Parameter is empty."); 234 NAPI_ASSERT(env, args[1] != nullptr, "Parameter is empty."); 235 NAPI_CALL(env, napi_typeof(env, args[0], &valuetype)); 236 NAPI_ASSERT(env, valuetype == napi_string, "Wrong argument typr. Object expected."); 237 NAPI_CALL(env, napi_typeof(env, args[1], &valuetype)); 238 NAPI_ASSERT(env, valuetype == napi_string, "Wrong argument typr. Object expected."); 239 XmlSerializer *object = nullptr; 240 NAPI_CALL(env, napi_unwrap(env, thisVar, reinterpret_cast<void**>(&object))); 241 std::string prefix; 242 std::string nsTemp; 243 XmlSerializer::DealNapiStrValue(env, args[0], prefix); 244 XmlSerializer::DealNapiStrValue(env, args[1], nsTemp); 245 object->SetNamespace(prefix, nsTemp); 246 napi_value result = nullptr; 247 NAPI_CALL(env, napi_get_undefined(env, &result)); 248 return result; 249 } 250 SetComment(napi_env env,napi_callback_info info)251 static napi_value SetComment(napi_env env, napi_callback_info info) 252 { 253 napi_value thisVar = nullptr; 254 size_t argc = 0; 255 napi_value args[1] = { 0 }; 256 NAPI_CALL(env, napi_get_cb_info(env, info, &argc, nullptr, &thisVar, nullptr)); 257 NAPI_CALL(env, napi_get_cb_info(env, info, &argc, args, &thisVar, nullptr)); 258 NAPI_ASSERT(env, argc == 1, "Wrong number of arguments"); 259 napi_valuetype valuetype = napi_null; 260 NAPI_ASSERT(env, args[0] != nullptr, "Parameter is empty)."); 261 NAPI_CALL(env, napi_typeof(env, args[0], &valuetype)); 262 NAPI_ASSERT(env, valuetype == napi_string, "Wrong argument typr. String expected"); 263 XmlSerializer *object = nullptr; 264 NAPI_CALL(env, napi_unwrap(env, thisVar, reinterpret_cast<void**>(&object))); 265 std::string comment; 266 object->DealNapiStrValue(env, args[0], comment); 267 object->SetComment(comment); 268 napi_value result = nullptr; 269 NAPI_CALL(env, napi_get_undefined(env, &result)); 270 return result; 271 } 272 SetCData(napi_env env,napi_callback_info info)273 static napi_value SetCData(napi_env env, napi_callback_info info) 274 { 275 napi_value thisVar = nullptr; 276 size_t argc = 0; 277 napi_value args[1] = { 0 }; 278 NAPI_CALL(env, napi_get_cb_info(env, info, &argc, nullptr, &thisVar, nullptr)); 279 NAPI_CALL(env, napi_get_cb_info(env, info, &argc, args, &thisVar, nullptr)); 280 NAPI_ASSERT(env, argc == 1, "Wrong number of arguments"); 281 napi_valuetype valuetype = napi_null; 282 NAPI_ASSERT(env, args[0] != nullptr, "Parameter is empty)."); 283 NAPI_CALL(env, napi_typeof(env, args[0], &valuetype)); 284 NAPI_ASSERT(env, valuetype == napi_string, "Wrong argument typr. String expected"); 285 XmlSerializer *object = nullptr; 286 NAPI_CALL(env, napi_unwrap(env, thisVar, reinterpret_cast<void**>(&object))); 287 std::string data; 288 XmlSerializer::DealNapiStrValue(env, args[0], data); 289 object->SetCData(data); 290 napi_value result = nullptr; 291 NAPI_CALL(env, napi_get_undefined(env, &result)); 292 return result; 293 } 294 SetText(napi_env env,napi_callback_info info)295 static napi_value SetText(napi_env env, napi_callback_info info) 296 { 297 napi_value thisVar = nullptr; 298 size_t argc = 0; 299 napi_value args[1] = { 0 }; 300 NAPI_CALL(env, napi_get_cb_info(env, info, &argc, nullptr, &thisVar, nullptr)); 301 NAPI_CALL(env, napi_get_cb_info(env, info, &argc, args, &thisVar, nullptr)); 302 NAPI_ASSERT(env, argc == 1, "Wrong number of arguments"); 303 napi_valuetype valuetype = napi_null; 304 NAPI_ASSERT(env, args[0] != nullptr, "Parameter is empty)."); 305 NAPI_CALL(env, napi_typeof(env, args[0], &valuetype)); 306 NAPI_ASSERT(env, valuetype == napi_string, "Wrong argument typr. String expected."); 307 XmlSerializer *object = nullptr; 308 NAPI_CALL(env, napi_unwrap(env, thisVar, reinterpret_cast<void**>(&object))); 309 std::string text; 310 XmlSerializer::DealNapiStrValue(env, args[0], text); 311 object->SetText(text); 312 napi_value result = nullptr; 313 NAPI_CALL(env, napi_get_undefined(env, &result)); 314 return result; 315 } 316 SetDocType(napi_env env,napi_callback_info info)317 static napi_value SetDocType(napi_env env, napi_callback_info info) 318 { 319 napi_value thisVar = nullptr; 320 size_t argc = 0; 321 napi_value args[1] = { 0 }; 322 NAPI_CALL(env, napi_get_cb_info(env, info, &argc, nullptr, &thisVar, nullptr)); 323 NAPI_CALL(env, napi_get_cb_info(env, info, &argc, args, &thisVar, nullptr)); 324 NAPI_ASSERT(env, argc == 1, "Wrong number of arguments"); 325 napi_valuetype valuetype = napi_null; 326 NAPI_ASSERT(env, args[0] != nullptr, "Parameter is empty)."); 327 NAPI_CALL(env, napi_typeof(env, args[0], &valuetype)); 328 NAPI_ASSERT(env, valuetype == napi_string, "Wrong argument typr. String expected."); 329 XmlSerializer *object = nullptr; 330 NAPI_CALL(env, napi_unwrap(env, thisVar, reinterpret_cast<void**>(&object))); 331 std::string text; 332 XmlSerializer::DealNapiStrValue(env, args[0], text); 333 object->SetDocType(text); 334 napi_value result = nullptr; 335 NAPI_CALL(env, napi_get_undefined(env, &result)); 336 return result; 337 } XmlSerializerError(napi_env env,napi_callback_info info)338 static napi_value XmlSerializerError(napi_env env, napi_callback_info info) 339 { 340 napi_value thisVar = nullptr; 341 napi_value result = nullptr; 342 NAPI_CALL(env, napi_get_cb_info(env, info, nullptr, nullptr, &thisVar, nullptr)); 343 XmlSerializer *object = nullptr; 344 NAPI_CALL(env, napi_unwrap(env, thisVar, reinterpret_cast<void**>(&object))); 345 std::string temp = object->XmlSerializerError(); 346 size_t templen = temp.size(); 347 NAPI_CALL(env, napi_create_string_utf8(env, temp.c_str(), templen, &result)); 348 return result; 349 } 350 XmlSerializerInit(napi_env env,napi_value exports)351 static napi_value XmlSerializerInit(napi_env env, napi_value exports) 352 { 353 const char *xmlSerializerClass = "XmlSerializer"; 354 napi_value xmlClass = nullptr; 355 napi_property_descriptor xmlDesc[] = { 356 DECLARE_NAPI_FUNCTION("setAttributes", SetAttributes), 357 DECLARE_NAPI_FUNCTION("addEmptyElement", AddEmptyElement), 358 DECLARE_NAPI_FUNCTION("setDeclaration", SetDeclaration), 359 DECLARE_NAPI_FUNCTION("startElement", StartElement), 360 DECLARE_NAPI_FUNCTION("endElement", EndElement), 361 DECLARE_NAPI_FUNCTION("setNamespace", SetNamespace), 362 DECLARE_NAPI_FUNCTION("setComment", SetComment), 363 DECLARE_NAPI_FUNCTION("setCDATA", SetCData), 364 DECLARE_NAPI_FUNCTION("setText", SetText), 365 DECLARE_NAPI_FUNCTION("setDocType", SetDocType), 366 DECLARE_NAPI_FUNCTION("XmlSerializerError", XmlSerializerError) 367 }; 368 NAPI_CALL(env, napi_define_class(env, xmlSerializerClass, strlen(xmlSerializerClass), XmlSerializerConstructor, 369 nullptr, sizeof(xmlDesc) / sizeof(xmlDesc[0]), xmlDesc, &xmlClass)); 370 napi_property_descriptor desc[] = { 371 DECLARE_NAPI_PROPERTY("XmlSerializer", xmlClass) 372 }; 373 napi_define_properties(env, exports, sizeof(desc) / sizeof(desc[0]), desc); 374 return exports; 375 } 376 Parse(napi_env env,napi_callback_info info)377 static napi_value Parse(napi_env env, napi_callback_info info) 378 { 379 napi_value thisVar = nullptr; 380 size_t argc = 0; 381 napi_value args[1] = { 0 }; 382 NAPI_CALL(env, napi_get_cb_info(env, info, &argc, nullptr, &thisVar, nullptr)); 383 NAPI_ASSERT(env, argc == 1, "Wrong number of arguments, one expected."); 384 NAPI_CALL(env, napi_get_cb_info(env, info, &argc, args, &thisVar, nullptr)); 385 NAPI_ASSERT(env, args[0] != nullptr, "Parameter is empty."); 386 napi_valuetype valuetype; 387 NAPI_CALL(env, napi_typeof(env, args[0], &valuetype)); 388 NAPI_ASSERT(env, valuetype == napi_object, "Wrong argument typr. Object expected."); 389 XmlPullParser *object = nullptr; 390 NAPI_CALL(env, napi_unwrap(env, thisVar, reinterpret_cast<void**>(&object))); 391 object->DealOptionInfo(env, args[0]); 392 object->Parse(env, thisVar); 393 napi_value result = nullptr; 394 NAPI_CALL(env, napi_get_undefined(env, &result)); 395 return result; 396 } 397 XmlPullParserError(napi_env env,napi_callback_info info)398 static napi_value XmlPullParserError(napi_env env, napi_callback_info info) 399 { 400 napi_value thisVar = nullptr; 401 napi_value result = nullptr; 402 NAPI_CALL(env, napi_get_cb_info(env, info, nullptr, nullptr, &thisVar, nullptr)); 403 XmlPullParser *object = nullptr; 404 NAPI_CALL(env, napi_unwrap(env, thisVar, reinterpret_cast<void**>(&object))); 405 std::string temp = object->XmlPullParserError(); 406 size_t templen = temp.size(); 407 NAPI_CALL(env, napi_create_string_utf8(env, temp.c_str(), templen, &result)); 408 return result; 409 } 410 XmlPullParserInit(napi_env env,napi_value exports)411 static napi_value XmlPullParserInit(napi_env env, napi_value exports) 412 { 413 const char *xmlPullParserClass = "XmlPullParser"; 414 napi_value xmlClass = nullptr; 415 napi_property_descriptor xmlDesc[] = { 416 DECLARE_NAPI_FUNCTION("parse", Parse), 417 DECLARE_NAPI_FUNCTION("XmlPullParserError", XmlPullParserError) 418 }; 419 NAPI_CALL(env, napi_define_class(env, xmlPullParserClass, strlen(xmlPullParserClass), 420 XmlPullParserConstructor, nullptr, sizeof(xmlDesc) / sizeof(xmlDesc[0]), 421 xmlDesc, &xmlClass)); 422 napi_property_descriptor desc[] = { 423 DECLARE_NAPI_PROPERTY("XmlPullParser", xmlClass) 424 }; 425 napi_define_properties(env, exports, sizeof(desc) / sizeof(desc[0]), desc); 426 return exports; 427 }; 428 Init(napi_env env,napi_value exports)429 static napi_value Init(napi_env env, napi_value exports) 430 { 431 XmlSerializerInit(env, exports); 432 XmlPullParserInit(env, exports); 433 return exports; 434 } 435 436 extern "C" NAPI_xml_GetJSCode(const char ** buf,int * bufLen)437 __attribute__((visibility("default"))) void NAPI_xml_GetJSCode(const char **buf, int *bufLen) 438 { 439 if (buf != nullptr) { 440 *buf = _binary_js_xml_js_start; 441 } 442 443 if (bufLen != nullptr) { 444 *bufLen = _binary_js_xml_js_end - _binary_js_xml_js_start; 445 } 446 } 447 extern "C" NAPI_xml_GetABCCode(const char ** buf,int * buflen)448 __attribute__((visibility("default"))) void NAPI_xml_GetABCCode(const char** buf, int* buflen) 449 { 450 if (buf != nullptr) { 451 *buf = _binary_xml_abc_start; 452 } 453 if (buflen != nullptr) { 454 *buflen = _binary_xml_abc_end - _binary_xml_abc_start; 455 } 456 } 457 458 459 static napi_module xmlModule = { 460 .nm_version = 1, 461 .nm_flags = 0, 462 .nm_filename = nullptr, 463 .nm_register_func = Init, 464 .nm_modname = "xml", 465 .nm_priv = reinterpret_cast<void*>(0), 466 .reserved = {0}, 467 }; RegisterModule()468 extern "C" __attribute__((constructor)) void RegisterModule() 469 { 470 napi_module_register(&xmlModule); 471 } 472 } // namespace OHOS::Xml 473