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