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 "securec.h" 18 namespace OHOS::xml { 19 static constexpr size_t CALLBACK_ARGS_COUNT = 3; 20 static constexpr size_t ATTRWITHTAG_ARGS_COUNT = 4; 21 DealNapiStrValue(napi_env env,const napi_value napiStr,std::string & result)22 napi_status XmlSerializer::DealNapiStrValue(napi_env env, const napi_value napiStr, std::string &result) 23 { 24 std::string buffer = ""; 25 size_t bufferSize = 0; 26 napi_status status = napi_ok; 27 status = napi_get_value_string_utf8(env, napiStr, nullptr, -1, &bufferSize); 28 buffer.reserve(bufferSize + 1); 29 buffer.resize(bufferSize); 30 if (status != napi_ok) { 31 HILOG_ERROR("XmlSerializer:: can not get buffer size"); 32 return status; 33 } 34 if (bufferSize > 0) { 35 status = napi_get_value_string_utf8(env, napiStr, buffer.data(), bufferSize + 1, &bufferSize); 36 if (status != napi_ok) { 37 HILOG_ERROR("XmlSerializer:: can not get buffer value"); 38 return status; 39 } 40 } 41 if (buffer.data() != nullptr) { 42 result = buffer; 43 } 44 return status; 45 } 46 SplicNsp()47 void XmlSerializer::SplicNsp() 48 { 49 elementStack[depth_ * 3] = elementStack[(depth_ - 1) * 3]; // 3: number of args 50 elementStack[depth_ * 3 + 1] = elementStack[(depth_ - 1) * 3 + 1]; // 3: number of args 51 if (multNsp[depth_ - 1].size() == 0) { 52 return; 53 } 54 if (type == "isAttri" || type == "isStart") { 55 for (int i = 0; i < curNspNum; ++i) { 56 out_.append(" xmlns:"); 57 out_.append(multNsp[depth_ - 1][i * 2]); // 2: number of args 58 out_.append("=\""); 59 out_.append(multNsp[depth_ - 1][i * 2 + 1]); // 2: number of args 60 out_.append("\""); 61 } 62 multNsp[depth_ - 1].clear(); 63 curNspNum = 0; 64 } 65 } 66 NextItem()67 void XmlSerializer::NextItem() 68 { 69 out_.append("\r\n"); 70 for (size_t i = 0; i < depth_; i++) { 71 out_.append(" "); 72 } 73 } 74 Replace(std::string str,const std::string & subStr,const std::string & repStr)75 std::string XmlSerializer::Replace(std::string str, const std::string &subStr, const std::string &repStr) 76 { 77 size_t iPos = 0; 78 size_t subLen = subStr.length(); 79 size_t step = repStr.length(); 80 while ((iPos = str.find(subStr, iPos)) != std::string::npos) { 81 str = str.substr(0, iPos) + repStr + str.substr(iPos + subLen); 82 iPos += step; 83 } 84 return str; 85 } 86 SetDeclaration()87 void XmlSerializer::SetDeclaration() 88 { 89 if (isHasDecl) { 90 xmlSerializerError_ = "illegal position for declaration"; 91 return; 92 } 93 isHasDecl = true; 94 out_ = ""; 95 out_.append("<?xml version=\"1.0\""); 96 out_.append(" encoding=\""); 97 out_.append(encoding_); 98 out_.append("\"?>"); 99 type = "isDecl"; 100 size_t iLenTemp = out_.length(); 101 if (iLength_ > iPos_ + iLenTemp - 1) { 102 if (memcpy_s(pStart_ + iPos_, iLength_ - iPos_, out_.c_str(), iLenTemp) == EOK) { 103 iPos_ += iLenTemp; 104 } else { 105 HILOG_ERROR("XmlSerializer:: SetDeclaration memcpy_s failed"); 106 } 107 } 108 } 109 SetNamespace(std::string prefix,const std::string & nsTemp)110 void XmlSerializer::SetNamespace(std::string prefix, const std::string &nsTemp) 111 { 112 out_ = ""; 113 if (type == "isStart" || type == "isAttri") { 114 SplicNsp(); 115 out_.append(">"); 116 } 117 elementStack[depth_ * 3] = prefix; // 3: number of args 118 elementStack[depth_ * 3 + 1] = nsTemp; // 3: number of args 119 multNsp[depth_][curNspNum * 2] = elementStack[depth_ * 3]; // 3: number of args 2: number of args 120 multNsp[depth_][curNspNum * 2 + 1] = elementStack[depth_ * 3 + 1]; // 3: number of args 2: number of args 121 ++curNspNum; 122 type = "isNsp"; 123 size_t iLenTemp = out_.length(); 124 if (iLength_ > iPos_ + iLenTemp - 1) { 125 if (memcpy_s(pStart_ + iPos_, iLength_ - iPos_, out_.c_str(), iLenTemp) == EOK) { 126 iPos_ += iLenTemp; 127 } else { 128 HILOG_ERROR("XmlSerializer:: SetNamespace memcpy_s failed"); 129 } 130 } 131 } 132 StartElement(const std::string & name)133 void XmlSerializer::StartElement(const std::string &name) 134 { 135 out_ = ""; 136 if (type == "isStart" || type == "isAttri") { 137 SplicNsp(); 138 out_.append(">"); 139 } 140 if (type != "" && type != "isDecl") { 141 NextItem(); 142 } 143 elementStack[depth_ * 3 + 2] = name; // 3: number of args 2: number of args 144 out_.append("<"); 145 if (elementStack[depth_ * 3] != "") { // 3: number of args 146 out_.append(elementStack[depth_ * 3]); // 3: number of args 147 out_.append(":"); 148 } else if (depth_ != 0) { 149 if (elementStack[(depth_ - 1) * 3] != "") { // 3: number of args 150 elementStack[depth_ * 3] = elementStack[(depth_ - 1) * 3]; // 3: number of args 151 out_.append(elementStack[depth_ * 3]); // 3: number of args 152 out_.append(":"); 153 } 154 } 155 out_.append(elementStack[depth_ * 3 + 2]); // 3: number of args 2: number of args 156 type = "isStart"; 157 ++depth_; 158 elementStack.push_back(""); 159 elementStack.push_back(""); 160 elementStack.push_back(""); 161 size_t iLenTemp = out_.length(); 162 if (iLength_ > iPos_ + iLenTemp - 1) { 163 if (memcpy_s(pStart_ + iPos_, iLength_ - iPos_, out_.c_str(), iLenTemp) == EOK) { 164 iPos_ += iLenTemp; 165 } else { 166 HILOG_ERROR("XmlSerializer:: StartElement memcpy_s failed"); 167 } 168 } 169 } 170 SetAttributes(const std::string & name,const std::string & value)171 void XmlSerializer::SetAttributes(const std::string &name, const std::string &value) 172 { 173 out_ = ""; 174 if (type != "isStart" && type != "isAttri") { 175 xmlSerializerError_ = "illegal position for attribute"; 176 } 177 out_.append(" "); 178 out_.append(name); 179 out_.append("=\""); 180 WriteEscaped(value); 181 out_.append("\""); 182 type = "isAttri"; 183 size_t iLenTemp = out_.length(); 184 if (iLength_ > iPos_ + iLenTemp - 1) { 185 if (memcpy_s(pStart_ + iPos_, iLength_ - iPos_, out_.c_str(), iLenTemp) == EOK) { 186 iPos_ += iLenTemp; 187 } else { 188 HILOG_ERROR("XmlSerializer:: SetAttributes memcpy_s failed"); 189 } 190 } 191 } 192 EndElement()193 void XmlSerializer::EndElement() 194 { 195 out_ = ""; 196 size_t iLenTemp = 0; 197 if (type == "isStart" || type == "isAttri") { 198 SplicNsp(); 199 out_.append("/>"); 200 type = "isEndTag"; 201 --depth_; 202 iLenTemp = out_.length(); 203 if (iLength_ > iPos_ + iLenTemp - 1) { 204 if (memcpy_s(pStart_ + iPos_, iLength_ - iPos_, out_.c_str(), iLenTemp) == EOK) { 205 iPos_ += iLenTemp; 206 } else { 207 HILOG_ERROR("XmlSerializer:: StartElement memcpy_s failed"); 208 } 209 } 210 return; 211 } 212 --depth_; 213 if (type != "isText") { 214 NextItem(); 215 } 216 out_.append("</"); 217 if (elementStack[depth_ * 3] != "") { // 3: number of args 218 out_.append(elementStack[depth_ * 3]); // 3: number of args 219 out_.append(":"); 220 } 221 out_.append(elementStack[depth_ * 3 + 2]); // 3: number of args 2: number of args 222 elementStack[depth_ * 3] = ""; // 3: number of args 223 elementStack[depth_ * 3 + 1] = ""; // 3: number of args 224 type = "isEndTag"; 225 out_.append(">"); 226 iLenTemp = out_.length(); 227 if (iLength_ > iPos_ + iLenTemp - 1) { 228 if (memcpy_s(pStart_ + iPos_, iLength_ - iPos_, out_.c_str(), iLenTemp) == EOK) { 229 iPos_ += iLenTemp; 230 } else { 231 HILOG_ERROR("XmlSerializer:: EndElement memcpy_s failed"); 232 } 233 } 234 } 235 AddEmptyElement(std::string name)236 void XmlSerializer::AddEmptyElement(std::string name) 237 { 238 out_ = ""; 239 if (type == "isStart" || type == "isAttri") { 240 SplicNsp(); 241 out_.append(">"); 242 } 243 if (type != "") { 244 NextItem(); 245 } 246 out_.append("<"); 247 out_.append(name); 248 out_.append("/>"); 249 type = "isAddEmpElem"; 250 size_t iLenTemp = out_.length(); 251 if (iLength_ > iPos_ + iLenTemp - 1) { 252 if (memcpy_s(pStart_ + iPos_, iLength_ - iPos_, out_.c_str(), iLenTemp) == EOK) { 253 iPos_ += iLenTemp; 254 } else { 255 HILOG_ERROR("XmlSerializer:: AddEmptyElement memcpy_s failed"); 256 } 257 } 258 } 259 SetText(const std::string & text)260 void XmlSerializer::SetText(const std::string &text) 261 { 262 out_ = ""; 263 if (type == "isStart" || type == "isAttri") { 264 SplicNsp(); 265 out_.append(">"); 266 } 267 WriteEscaped(text); 268 type = "isText"; 269 size_t iLenTemp = out_.length(); 270 if (iLength_ > iPos_ + iLenTemp - 1) { 271 if (memcpy_s(pStart_ + iPos_, iLength_ - iPos_, out_.c_str(), iLenTemp) == EOK) { 272 iPos_ += iLenTemp; 273 } else { 274 HILOG_ERROR("XmlSerializer:: SetText memcpy_s failed"); 275 } 276 } 277 } 278 SetComment(const std::string & comment)279 void XmlSerializer::SetComment(const std::string &comment) 280 { 281 out_ = ""; 282 if (type == "isStart" || type == "isAttri") { 283 SplicNsp(); 284 out_.append(">"); 285 } 286 if (type != "") { 287 NextItem(); 288 } 289 out_ += "<!--" + comment + "-->"; 290 type = "isCom"; 291 size_t iLenTemp = out_.length(); 292 if (iLength_ > iPos_ + iLenTemp - 1) { 293 if (memcpy_s(pStart_ + iPos_, iLength_ - iPos_, out_.c_str(), iLenTemp) == EOK) { 294 iPos_ += iLenTemp; 295 } else { 296 HILOG_ERROR("XmlSerializer:: SetComment memcpy_s failed"); 297 } 298 } 299 } 300 SetCData(std::string data)301 void XmlSerializer::SetCData(std::string data) 302 { 303 out_ = ""; 304 if (type == "isStart" || type == "isAttri") { 305 SplicNsp(); 306 out_.append(">"); 307 } 308 if (type != "") { 309 NextItem(); 310 } 311 data = Replace(data, "]]>", "]]]]><![CDATA[>"); 312 out_ += "<![CDATA[" + data + "]]>"; 313 type = "isCData"; 314 size_t iLenTemp = out_.length(); 315 if (iLength_ > iPos_ + iLenTemp - 1) { 316 if (memcpy_s(pStart_ + iPos_, iLength_ - iPos_, out_.c_str(), iLenTemp) == EOK) { 317 iPos_ += iLenTemp; 318 } else { 319 HILOG_ERROR("XmlSerializer:: SetCData memcpy_s failed"); 320 } 321 } 322 } 323 SetDocType(const std::string & text)324 void XmlSerializer::SetDocType(const std::string &text) 325 { 326 out_ = ""; 327 if (type == "isStart" || type == "isAttri") { 328 SplicNsp(); 329 out_.append(">"); 330 } 331 if (type != "") { 332 NextItem(); 333 } 334 out_ += "<!DOCTYPE " + text + ">"; 335 type = "isDocType"; 336 size_t iLenTemp = out_.length(); 337 if (iLength_ > iPos_ + iLenTemp - 1) { 338 if (memcpy_s(pStart_ + iPos_, iLength_ - iPos_, out_.c_str(), iLenTemp) == EOK) { 339 iPos_ += iLenTemp; 340 } else { 341 HILOG_ERROR("XmlSerializer:: SetDocType memcpy_s failed"); 342 } 343 } 344 } 345 WriteEscaped(std::string s)346 void XmlSerializer::WriteEscaped(std::string s) 347 { 348 size_t len = s.length(); 349 for (size_t i = 0; i < len; ++i) { 350 char c = s[i]; 351 switch (c) { 352 case '\'': 353 out_.append("'"); 354 break; 355 case '\"': 356 out_.append("""); 357 break; 358 case '&': 359 out_.append("&"); 360 break; 361 case '>': 362 out_.append(">"); 363 break; 364 case '<': 365 out_.append("<"); 366 break; 367 default: 368 out_ += c; 369 } 370 } 371 } 372 XmlSerializerError()373 std::string XmlSerializer::XmlSerializerError() 374 { 375 return xmlSerializerError_; 376 } 377 DealOptionInfo(napi_env env,napi_value napiObj)378 napi_value XmlPullParser::DealOptionInfo(napi_env env, napi_value napiObj) 379 { 380 std::vector<std::string> vctOptions = { 381 "supportDoctype", "ignoreNameSpace", "tagValueCallbackFunction", 382 "attributeValueCallbackFunction", "tokenValueCallbackFunction", "attributeWithTagCallbackFunction" 383 }; 384 size_t vctLength = vctOptions.size(); 385 for (size_t i = 0; i < vctLength; ++i) { 386 napi_value recvTemp = nullptr; 387 bool bRecv = false; 388 napi_get_named_property(env, napiObj, vctOptions[i].c_str(), &recvTemp); 389 napi_valuetype valuetype; 390 NAPI_CALL(env, napi_typeof(env, recvTemp, &valuetype)); 391 if (valuetype == napi_boolean && (napi_get_value_bool(env, recvTemp, &bRecv)) == napi_ok) { 392 switch (i) { 393 case 0: // 0:supportDoctype 394 bDoctype_ = bRecv; 395 break; 396 case 1: // 1:ignoreNameSpace 397 bIgnoreNS_ = bRecv; 398 break; 399 default: 400 break; 401 } 402 } else if (valuetype == napi_function) { 403 NAPI_ASSERT(env, recvTemp != nullptr, "Parameter is empty."); 404 switch (i) { 405 case 2: // 2:tagValueCallbackFunction 406 tagFunc_ = recvTemp; 407 break; 408 case 3: // 3:attributeValueCallbackFunction 409 attrFunc_ = recvTemp; 410 break; 411 case 4: // 4:tokenValueCallbackFunction 412 tokenFunc_ = recvTemp; 413 break; 414 case 5: // 5:attributeWithTagCallbackFunction 415 attrWithTagFunc_ = recvTemp; 416 break; 417 default: 418 break; 419 } 420 } 421 } 422 return nullptr; 423 } 424 PushSrcLinkList(std::string strBuffer)425 void XmlPullParser::PushSrcLinkList(std::string strBuffer) 426 { 427 auto pNew = new SrcLinkList; 428 srcLinkList_->next = pNew; 429 pNew->strBuffer = strBuffer; 430 pNew->position = 0; 431 pNew->max = strBuffer.size(); 432 srcLinkList_ = pNew; 433 } 434 PopSrcLinkList()435 void XmlPullParser::PopSrcLinkList() 436 { 437 SrcLinkList* pTemp = srcLinkList_; 438 if (srcLinkList_) { 439 srcLinkList_ = srcLinkList_->next; 440 } 441 if (pTemp != nullptr) { 442 delete pTemp; 443 pTemp = nullptr; 444 } 445 } 446 DealLength(size_t minimum)447 bool XmlPullParser::DealLength(size_t minimum) 448 { 449 while (srcLinkList_->next != nullptr) { 450 if (position_ < max_) { 451 xmlPullParserError_ = "Unbalanced entity!"; 452 } 453 PopSrcLinkList(); 454 if (max_ - position_ >= minimum) { 455 return true; 456 } 457 } 458 for (size_t i = 0; i < position_; i++) { 459 if (strXml_[i] == '\n') { 460 bufferStartLine_++; 461 bufferStartColumn_ = 0; 462 } else { 463 bufferStartColumn_++; 464 } 465 } 466 if (keyInfo_ != "") { 467 keyInfo_.append(strXml_, 0, position_); 468 } 469 470 if (max_ > position_) { 471 max_ -= position_; 472 for (size_t j = 0; j < max_; ++j) { 473 strXml_[j] = strXml_[position_ + j]; 474 } 475 } else { 476 max_ = 0; 477 } 478 if (position_ != strXml_.size()) { 479 position_ = 0; 480 } 481 if (strXml_.size() - max_ > 0 && position_ == 0) { 482 max_ += strXml_.size() - max_; 483 if (max_ >= minimum) { 484 return true; 485 } 486 } 487 return false; 488 } 489 GetNSCount(size_t iTemp)490 size_t XmlPullParser::GetNSCount(size_t iTemp) 491 { 492 if (iTemp > depth) { 493 xmlPullParserError_ = " IndexOutOfBoundsException"; 494 } 495 return nspCounts_[depth]; 496 } 497 XmlPullParserError() const498 std::string XmlPullParser::XmlPullParserError() const 499 { 500 return xmlPullParserError_; 501 } 502 ParseTag(napi_env env,napi_value thisVar) const503 bool XmlPullParser::ParseTag(napi_env env, napi_value thisVar) const 504 { 505 napi_value returnVal = nullptr; 506 napi_value global = nullptr; 507 napi_get_global(env, &global); 508 napi_value key = nullptr; 509 napi_create_string_utf8(env, name_.c_str(), name_.size(), &key); 510 napi_value value = nullptr; 511 napi_create_string_utf8(env, text_.c_str(), text_.size(), &value); 512 napi_value argv[CALLBACK_ARGS_COUNT] = {key, value, thisVar}; 513 napi_call_function(env, global, tagFunc_, CALLBACK_ARGS_COUNT, argv, &returnVal); 514 bool bRec = true; 515 napi_get_value_bool(env, returnVal, &bRec); 516 return bRec; 517 } 518 ParseToken(napi_env env,napi_value thisVar) const519 bool XmlPullParser::ParseToken(napi_env env, napi_value thisVar) const 520 { 521 napi_handle_scope scope = nullptr; 522 napi_status status = napi_open_handle_scope(env, &scope); 523 if (status != napi_ok) { 524 HILOG_ERROR("XmlPullParser::open scope failed!"); 525 return false; 526 } 527 napi_value returnVal = nullptr; 528 size_t argc = 2; // 2: number of args 529 napi_value key = nullptr; 530 napi_create_int32(env, (int)type, &key); 531 napi_value parseInfo = nullptr; 532 napi_create_object(env, &parseInfo); 533 auto object = new ParseInfo(); 534 napi_wrap(env, parseInfo, object, nullptr, nullptr, nullptr); 535 static napi_property_descriptor xmlDesc[] = { 536 DECLARE_NAPI_FUNCTION("getDepth", XmlPullParser::ParseInfo::GetDepth), 537 DECLARE_NAPI_FUNCTION("getColumnNumber", XmlPullParser::ParseInfo::GetColumnNumber), 538 DECLARE_NAPI_FUNCTION("getLineNumber", XmlPullParser::ParseInfo::GetLineNumber), 539 DECLARE_NAPI_FUNCTION("getAttributeCount", XmlPullParser::ParseInfo::GetAttributeCount), 540 DECLARE_NAPI_FUNCTION("getName", XmlPullParser::ParseInfo::GetName), 541 DECLARE_NAPI_FUNCTION("getNamespace", XmlPullParser::ParseInfo::GetNamespace), 542 DECLARE_NAPI_FUNCTION("getPrefix", XmlPullParser::ParseInfo::GetPrefix), 543 DECLARE_NAPI_FUNCTION("getText", XmlPullParser::ParseInfo::GetText), 544 DECLARE_NAPI_FUNCTION("isEmptyElementTag", XmlPullParser::ParseInfo::IsEmptyElementTag), 545 DECLARE_NAPI_FUNCTION("isWhitespace", XmlPullParser::ParseInfo::IsWhitespace) 546 }; 547 napi_define_properties(env, parseInfo, sizeof(xmlDesc) / sizeof(xmlDesc[0]), xmlDesc); 548 napi_set_named_property(env, parseInfo, "MainInfo", thisVar); 549 napi_value argv[2] = {key, parseInfo}; // 2: number of args 550 napi_call_function(env, parseInfo, tokenFunc_, argc, argv, &returnVal); 551 bool bRec = false; 552 napi_get_value_bool(env, returnVal, &bRec); 553 if (object != nullptr) { 554 delete object; 555 object = nullptr; 556 } 557 napi_close_handle_scope(env, scope); 558 return bRec; 559 } 560 ParseAttri(napi_env env,napi_value thisVar,napi_value attriFun) const561 bool XmlPullParser::ParseAttri(napi_env env, napi_value thisVar, napi_value attriFun) const 562 { 563 napi_handle_scope scope = nullptr; 564 napi_status status_scope = napi_open_handle_scope(env, &scope); 565 if (status_scope != napi_ok) { 566 HILOG_ERROR("XmlPullParser::open scope failed!"); 567 return false; 568 } 569 for (size_t i = 0; i < attriCount_; ++i) { 570 napi_value returnVal = nullptr; 571 napi_value global = nullptr; 572 napi_get_global(env, &global); 573 napi_value key = nullptr; 574 napi_create_string_utf8(env, attributes[i * 4 + 2].c_str(), // 4 and 2: number of args 575 attributes[i * 4 + 2].size(), &key); // 4 and 2: number of args 576 napi_value value = nullptr; 577 napi_create_string_utf8(env, attributes[i * 4 + 3].c_str(), // 4 and 3: number of args 578 attributes[i * 4 + 3].size(), &value); // 3 and 4: number of args 579 if (attriFun == attrFunc_) { 580 napi_value argv[CALLBACK_ARGS_COUNT] = {key, value, thisVar}; 581 napi_call_function(env, global, attriFun, CALLBACK_ARGS_COUNT, argv, &returnVal); 582 } else { 583 napi_value tagName = nullptr; 584 napi_create_string_utf8(env, name_.c_str(), name_.size(), &tagName); 585 napi_value argsv[ATTRWITHTAG_ARGS_COUNT] = {tagName, key, value, thisVar}; 586 napi_call_function(env, global, attriFun, ATTRWITHTAG_ARGS_COUNT, argsv, &returnVal); 587 } 588 bool bRec = false; 589 napi_get_value_bool(env, returnVal, &bRec); 590 if (!bRec) { 591 napi_close_handle_scope(env, scope); 592 return bRec; 593 } 594 } 595 napi_close_handle_scope(env, scope); 596 return true; 597 } 598 HandleTagFunc(napi_env env,napi_value thisVar)599 bool XmlPullParser::HandleTagFunc(napi_env env, napi_value thisVar) 600 { 601 if (!tagFunc_) { 602 return true; 603 } 604 bool bRec = ParseTag(env, thisVar); 605 if (!bRec && type == TagEnum::START_TAG) { 606 return false; 607 } 608 return true; 609 } 610 HandleTokenFunc(napi_env env,napi_value thisVar)611 bool XmlPullParser::HandleTokenFunc(napi_env env, napi_value thisVar) 612 { 613 if (!tokenFunc_) { 614 return true; 615 } 616 return ParseToken(env, thisVar); 617 } 618 HandleAttrWithTagFunc(napi_env env,napi_value thisVar)619 bool XmlPullParser::HandleAttrWithTagFunc(napi_env env, napi_value thisVar) 620 { 621 if (!(attrWithTagFunc_ && attriCount_)) { 622 return true; 623 } 624 bool bRec = ParseAttri(env, thisVar, attrWithTagFunc_); 625 attriCount_ = 0; 626 return bRec; 627 } 628 629 /** 630 * This function will be deprecated in the future due to a bug. 631 * After parsing the data, since the variable attriCount_ was reset to 0, 632 * The program cannot stop normally because it cannot enter the 'return false' branch. 633 */ HandleAttrFunc(napi_env env,napi_value thisVar)634 bool XmlPullParser::HandleAttrFunc(napi_env env, napi_value thisVar) 635 { 636 if (!(attrFunc_ && attriCount_)) { 637 return true; 638 } 639 bool bRec = ParseAttri(env, thisVar, attrFunc_); 640 attriCount_ = 0; 641 if (attriCount_ && !bRec) { 642 return false; 643 } 644 return true; 645 } 646 DealCdata(std::string data)647 std::string XmlPullParser::DealCdata(std::string data) 648 { 649 std::string_view cDataBegin = "<![CDATA["; 650 std::string_view cDataEnd = "]]>"; 651 size_t foundPosBegin = data.find(cDataBegin); 652 size_t foundPosEnd = data.find(cDataEnd); 653 size_t count = 0; 654 while (foundPosBegin != std::string::npos) { 655 std::string temp = data.substr(foundPosBegin, foundPosEnd - foundPosBegin + cDataEnd.length()); 656 std::string resStr = ""; 657 for (char c : temp) { 658 if (c == '\r') { 659 resStr += "\\r"; 660 count++; 661 } else if (c == '\n') { 662 resStr += "\\n"; 663 count++; 664 } else { 665 resStr += c; 666 } 667 } 668 data.replace(foundPosBegin, temp.length(), resStr); 669 foundPosBegin = data.find(cDataBegin, foundPosBegin + 1); 670 foundPosEnd = data.find(cDataEnd, foundPosEnd + count + 1); 671 } 672 return data; 673 } 674 Parse(napi_env env,napi_value thisVar,bool deprecated)675 void XmlPullParser::Parse(napi_env env, napi_value thisVar, bool deprecated) 676 { 677 napi_handle_scope scope = nullptr; 678 napi_status status_scope = napi_open_handle_scope(env, &scope); 679 if (status_scope != napi_ok) { 680 HILOG_ERROR("XmlPullParser::open scope failed!"); 681 return; 682 } 683 if (deprecated) { 684 strXml_ = DealCdata(strXml_); 685 } 686 if (tagFunc_ || attrFunc_ || tokenFunc_ || attrWithTagFunc_) { 687 while (type != TagEnum::END_DOCUMENT) { 688 if (ParseOneTag() == TagEnum::ERROR) { 689 break; 690 } 691 if (!HandleTagFunc(env, thisVar)) { 692 break; 693 } 694 if (!HandleTokenFunc(env, thisVar)) { 695 break; 696 } 697 if (!HandleAttrWithTagFunc(env, thisVar)) { 698 break; 699 } 700 if (!HandleAttrFunc(env, thisVar)) { 701 break; 702 } 703 } 704 } 705 napi_close_handle_scope(env, scope); 706 } 707 DealExclamationGroup()708 TagEnum XmlPullParser::DealExclamationGroup() 709 { 710 switch (strXml_[position_ + 2]) { // 2: number of args 711 case 'D': 712 return TagEnum::DOCDECL; 713 case '[': 714 return TagEnum::CDSECT; 715 case '-': 716 return TagEnum::COMMENT; 717 case 'E': 718 switch (strXml_[position_ + 3]) { // 3: number of args 719 case 'L': 720 return TagEnum::ELEMENTDECL; 721 case 'N': 722 return TagEnum::ENTITYDECL; 723 default: 724 break; 725 } 726 xmlPullParserError_ = "Unexpected <!"; 727 break; 728 case 'A': 729 return TagEnum::ATTLISTDECL; 730 case 'N': 731 return TagEnum::NOTATIONDECL; 732 default: 733 break; 734 } 735 return TagEnum::ERROR; 736 } 737 DealLtGroup()738 TagEnum XmlPullParser::DealLtGroup() 739 { 740 if (position_ + 3 >= max_ && !DealLength(4)) { // 4: number of args 3: number of args 741 xmlPullParserError_ = ("Dangling <"); 742 } 743 char cTemp = strXml_[position_ + 1]; 744 if (cTemp == '/') { 745 return TagEnum::END_TAG; 746 } else if (cTemp == '?') { 747 std::string strXml = strXml_.substr(position_ + 2, 4); // 2 and 4:position and length 748 MakeStrUpper(strXml); 749 if (max_ >= position_ + 5 && strXml == tagText_.XML) { // 5: number of args 750 return TagEnum::XML_DECLARATION; 751 } else { 752 return TagEnum::INSTRUCTION; 753 } 754 } else if (cTemp == '!') { 755 return DealExclamationGroup(); 756 } else { 757 return TagEnum::START_TAG; 758 } 759 } 760 ParseTagType(bool inDeclaration)761 TagEnum XmlPullParser::ParseTagType(bool inDeclaration) 762 { 763 if (bStartDoc_) { 764 bStartDoc_ = false; 765 return TagEnum::START_DOCUMENT; 766 } 767 if (position_ >= max_ && !DealLength(1)) { 768 return TagEnum::END_DOCUMENT; 769 } 770 switch (strXml_[position_]) { 771 case '&': 772 if (apiVersion_ >= APIVerIsolation_.API12) { 773 return TagEnum::ENTITY_REFERENCE; 774 } else { 775 return inDeclaration ? TagEnum::ENTITY_REFERENCE : TagEnum::TEXT; 776 } 777 case '<': 778 return DealLtGroup(); 779 case '%': 780 return inDeclaration ? TagEnum::PARAMETER_ENTITY_REF : TagEnum::TEXT; 781 default: 782 return TagEnum::TEXT; 783 } 784 } 785 MakeStrUpper(std::string & src) const786 void XmlPullParser::MakeStrUpper(std::string &src) const 787 { 788 size_t i = 0; 789 790 while (i < src.size()) { 791 if (src[i] >= 'A' && src[i] <= 'Z') { 792 src[i] += 32; // 32: number of args 793 } 794 ++i; 795 } 796 } 797 SkipText(std::string chars)798 void XmlPullParser::SkipText(std::string chars) 799 { 800 if (position_ + chars.size() > max_ && !DealLength(chars.size())) { 801 xmlPullParserError_ = "expected: '" + chars + "' but was EOF"; 802 return; 803 } 804 size_t len = chars.length(); 805 if (strXml_.substr(position_, len) != chars) { 806 xmlPullParserError_ = "expected: \"" + chars + "\" but was \"" + strXml_.substr(position_, len) + "...\""; 807 } 808 position_ += len; 809 } 810 PriorDealChar()811 int XmlPullParser::PriorDealChar() 812 { 813 if (position_ < max_ || DealLength(1)) { 814 return strXml_[position_]; 815 } 816 return -1; 817 } 818 SkipChar(char expected)819 void XmlPullParser::SkipChar(char expected) 820 { 821 int c = PriorDealChar(); 822 if (c != expected) { 823 xmlPullParserError_ = "expected:"; 824 if (c == -1) { 825 return; 826 } 827 } 828 position_++; 829 } 830 ParseNameInner(size_t start)831 std::string XmlPullParser::ParseNameInner(size_t start) 832 { 833 std::string result = ""; 834 char c = 0; 835 while (true) { 836 if (position_ >= max_) { 837 result.append(strXml_, start, position_ - start); 838 if (!DealLength(1)) { 839 return result; 840 } 841 start = position_; 842 } 843 c = strXml_[position_]; 844 if ((c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') || 845 (c >= '0' && c <= '9') || c == '_' || c == '-' || 846 c == ':' || c == '.') { 847 position_++; 848 continue; 849 } 850 result.append(strXml_, start, position_ - start); 851 return result; 852 } 853 } 854 ParseName()855 std::string XmlPullParser::ParseName() 856 { 857 if (position_ >= max_ && !DealLength(1)) { 858 xmlPullParserError_ = "name expected"; 859 return ""; 860 } 861 size_t start = position_; 862 char c = strXml_[position_]; 863 if ((c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') || 864 c == '_' || c == ':' || relaxed) { 865 position_++; 866 } else { 867 xmlPullParserError_ = "The node name contains invalid characters: "; 868 xmlPullParserError_ += c; 869 return ""; 870 } 871 return ParseNameInner(start); 872 } 873 SkipInvalidChar()874 void XmlPullParser::SkipInvalidChar() 875 { 876 while (position_ < max_ || DealLength(1)) { 877 unsigned char temp = strXml_[position_]; 878 if (temp > ' ') { 879 break; 880 } 881 position_++; 882 } 883 } 884 ParseEntityFunc(size_t start,std::string & out,bool isEntityToken,TextEnum textEnum)885 void XmlPullParser::ParseEntityFunc(size_t start, std::string &out, bool isEntityToken, TextEnum textEnum) 886 { 887 std::string strEntity = out.substr(start + 1, out.length() - 1); 888 if (isEntityToken) { 889 name_ = strEntity; 890 } 891 if (strEntity.size() && strEntity[0] == '#') { 892 int c = 0; 893 if (strEntity.size() >= 2 && strEntity[1] == 'x') { // 2: number of args 894 c = std::stoi(strEntity.substr(2), nullptr, 16); // 16: number of args 2: number of args 895 } else { 896 c = std::stoi(strEntity.substr(1), nullptr); 897 } 898 out = ""; 899 out += static_cast<char>(c); 900 bUnresolved_ = false; 901 return; 902 } 903 if (textEnum == TextEnum::ENTITY_DECL) { 904 return; 905 } 906 if (DEFAULT_ENTITIES.count(strEntity) != 0) { 907 out = out.substr(0, start); 908 bUnresolved_ = false; 909 out.append(DEFAULT_ENTITIES[strEntity]); 910 return; 911 } 912 std::string resolved = " "; 913 if (documentEntities.size() != 0 && (resolved = strEntity) != "") { 914 out = ""; 915 bUnresolved_ = false; 916 if (bDocDecl) { 917 PushSrcLinkList(resolved); 918 } else { 919 out.append(resolved); 920 } 921 return; 922 } 923 if (sysInfo_ != "") { 924 out = ""; 925 return; 926 } 927 bUnresolved_ = true; 928 } 929 ParseEntity(std::string & out,bool isEntityToken,bool throwOnResolveFailure,TextEnum textEnum)930 void XmlPullParser::ParseEntity(std::string &out, 931 bool isEntityToken, 932 bool throwOnResolveFailure, 933 TextEnum textEnum) 934 { 935 size_t start = out.length(); 936 if (strXml_[position_++] != '&') { 937 xmlPullParserError_ = "Should not be reached"; 938 } 939 out += '&'; 940 while (true) { 941 int c = PriorDealChar(); 942 if (c == ';') { 943 out += ';'; 944 position_++; 945 break; 946 } else if (c >= 128 || // 128: number of args 947 (c >= '0' && c <= '9') || 948 (c >= 'a' && c <= 'z') || 949 (c >= 'A' && c <= 'Z') || 950 c == '_' || 951 c == '-' || 952 c == '#') { 953 position_++; 954 out.push_back(static_cast<char>(c)); 955 } else if (relaxed) { 956 return; 957 } else { 958 xmlPullParserError_ = "unterminated entity ref"; 959 break; 960 } 961 } 962 ParseEntityFunc(start, out, isEntityToken, textEnum); 963 } 964 ParseTagValueFunc(char & c,bool bFlag,TextEnum textEnum,size_t & start,std::string & result)965 bool XmlPullParser::ParseTagValueFunc(char &c, bool bFlag, TextEnum textEnum, 966 size_t &start, std::string &result) 967 { 968 if (c == '\r') { 969 if ((position_ + 1 < max_ || DealLength(2)) && strXml_[position_ + 1] == '\n') { // 2: number of args 970 position_++; 971 } 972 c = (textEnum == TextEnum::ATTRI) ? ' ' : '\n'; 973 } else if (c == '\n') { 974 c = ' '; 975 } else if (c == '&') { 976 bWhitespace_ = false; 977 ParseEntity(result, false, bFlag, textEnum); 978 start = position_; 979 return false; 980 } else if (c == '<') { 981 if (textEnum == TextEnum::ATTRI) { 982 xmlPullParserError_ = "Illegal: \"<\" inside attribute value"; 983 } 984 bWhitespace_ = false; 985 } else if (c == ']') { 986 if ((position_ + 2 < max_ || DealLength(3)) && // 2: number of args 3: number of args 987 strXml_[position_ + 1] == ']' && strXml_[position_ + 2] == '>') { // 2: number of args 988 xmlPullParserError_ = "Illegal: \"]]>\" outside CDATA section"; 989 } 990 bWhitespace_ = false; 991 } else if (c == '%') { 992 xmlPullParserError_ = "This parser doesn't support parameter entities"; 993 } else { 994 xmlPullParserError_ = "AssertionError"; 995 } 996 return true; 997 } 998 DealWhiteSpace(unsigned char c)999 void XmlPullParser::DealWhiteSpace(unsigned char c) 1000 { 1001 if (bWhitespace_ && c <= ' ') { 1002 bWhitespace_ = true; 1003 } else { 1004 bWhitespace_ = false; 1005 } 1006 } 1007 ParseTagValueInner(size_t & start,std::string & result,char delimiter,TextEnum textEnum,bool bFlag)1008 size_t XmlPullParser::ParseTagValueInner(size_t &start, std::string &result, 1009 char delimiter, TextEnum textEnum, bool bFlag) 1010 { 1011 if (position_ >= max_) { 1012 if (start < position_) { 1013 result.append(strXml_, start, position_ - start); 1014 } 1015 if (!DealLength(1)) { 1016 result = (result != "" ? result : ""); 1017 return 0; 1018 } 1019 start = position_; 1020 } 1021 unsigned char c = strXml_[position_]; 1022 if (c == delimiter || 1023 (delimiter == ' ' && (c <= ' ' || c == '>')) || 1024 (c == '&' && !bFlag)) { 1025 return 1; 1026 } 1027 if (c != '\r' && (c != '\n' || textEnum != TextEnum::ATTRI) && 1028 c != '&' && c != '<' && (c != ']' || textEnum != TextEnum::TEXT) && 1029 (c != '%' || textEnum != TextEnum::ENTITY_DECL)) { 1030 DealWhiteSpace(c); 1031 position_++; 1032 return 2; // 2: break flag 1033 } 1034 result.append(strXml_, start, position_ - start); 1035 return c; 1036 } 1037 ParseTagValue(char delimiter,bool resolveEntities,bool throwOnResolveFailure,TextEnum textEnum)1038 std::string XmlPullParser::ParseTagValue(char delimiter, bool resolveEntities, 1039 bool throwOnResolveFailure, TextEnum textEnum) 1040 { 1041 size_t start = position_; 1042 std::string result = ""; 1043 if (textEnum == TextEnum::TEXT && text_ != "") { 1044 result.append(text_); 1045 } 1046 while (true) { 1047 char cRecv = static_cast<char>(ParseTagValueInner(start, result, delimiter, textEnum, resolveEntities)); 1048 if (cRecv == 0) { 1049 return result; 1050 } else if (cRecv == 1) { 1051 break; 1052 } else if (cRecv == 2) { // 2: break flag 1053 continue; 1054 } else if (!ParseTagValueFunc(cRecv, throwOnResolveFailure, textEnum, start, result)) { 1055 continue; 1056 } 1057 ++position_; 1058 result = result + static_cast<char>(cRecv); 1059 start = position_; 1060 } 1061 result.append(strXml_, start, position_ - start); 1062 return result; 1063 } 1064 GetNamespace(const std::string & prefix)1065 std::string XmlPullParser::GetNamespace(const std::string &prefix) 1066 { 1067 size_t temp = GetNSCount(depth) << 1; 1068 if (temp) { 1069 size_t i = temp - 2; // 2: number of args 1070 for (; i >= 0; i -= 2) { // 2: number of args 1071 if (prefix == "" && nspStack_[i] == "") { 1072 return nspStack_[i + 1]; 1073 } else if (prefix == nspStack_[i]) { 1074 return nspStack_[i + 1]; 1075 } 1076 if (!i) { 1077 break; 1078 } 1079 } 1080 } 1081 return ""; 1082 } 1083 Replace(std::string & strTemp,std::string strSrc,std::string strDes) const1084 void XmlPullParser::Replace(std::string& strTemp, std::string strSrc, std::string strDes) const 1085 { 1086 size_t iPos = 0; 1087 while ((iPos = strTemp.find(strSrc)) != std::string::npos) { 1088 strTemp.replace(iPos, strSrc.size(), strDes); 1089 } 1090 } 1091 ParseNspFunc(size_t & i,const std::string & attrName,bool & any)1092 void XmlPullParser::ParseNspFunc(size_t &i, const std::string &attrName, bool &any) 1093 { 1094 size_t j = (nspCounts_[depth]++) << 1; 1095 size_t uiSize = nspStack_.size(); 1096 if (uiSize < j + 2) { // 2: number of args 1097 nspStack_.resize(j + 16); // 16: number of args 1098 } 1099 nspStack_[j] = attrName; 1100 nspStack_[j + 1] = attributes[i + 3]; // 3: number of args 1101 if (attrName != "" && attributes[i + 3].empty()) { // 3: number of args 1102 xmlPullParserError_ = "illegal empty namespace"; 1103 } 1104 if (bKeepNsAttri) { 1105 attributes[i] = "http://www.w3.org/2000/xmlns/"; 1106 any = true; 1107 } else { 1108 for (size_t iCount = i; iCount < ((--attriCount_) << 2); ++iCount) { // 2: number of args 1109 attributes[iCount] = attributes[iCount + 4]; // 4: number of args 1110 } 1111 i -= 4; // 4: 1112 } 1113 } 1114 ParseNspFunction()1115 void XmlPullParser::ParseNspFunction() 1116 { 1117 int i = (attriCount_ << 2) - 4; // 4: number of args 2: number of args 1118 for (; i >= 0; i -= 4) { // 4: number of args 1119 std::string attrName = attributes[i + 2]; // 2: number of args 1120 size_t cut = attrName.find(':'); 1121 if (cut == 0 && !relaxed) { 1122 xmlPullParserError_ = "illegal attribute name: "; 1123 } else if (cut != std::string::npos) { 1124 std::string attrPrefix = attrName.substr(0, cut); 1125 attrName = attrName.substr(cut + 1); 1126 std::string attrNs = GetNamespace(attrPrefix); 1127 if (attrNs == "" && !relaxed) { 1128 xmlPullParserError_ = ("Undefined Prefix: " + attrPrefix + " in "); 1129 } 1130 attributes[i] = attrNs; 1131 attributes[i + 1] = attrPrefix; 1132 attributes[i + 2] = attrName; // 2: number of args 1133 } 1134 } 1135 } 1136 ParseNsp()1137 bool XmlPullParser::ParseNsp() 1138 { 1139 bool any = false; 1140 size_t cut = 0; 1141 for (size_t i = 0; i < (attriCount_ << 2); i += 4) { // 2 and 4: number of args 1142 std::string attrName = attributes[i + 2]; // 2: number of args 1143 cut = attrName.find(':'); 1144 std::string prefix; 1145 if (cut != std::string::npos) { 1146 prefix = attrName.substr(0, cut); 1147 attrName = attrName.substr(cut + 1); 1148 } else if (attrName == ("xmlns")) { 1149 prefix = attrName; 1150 attrName = ""; 1151 } else { 1152 continue; 1153 } 1154 if (!(prefix == "xmlns")) { 1155 any = true; 1156 } else { 1157 ParseNspFunc(i, attrName, any); 1158 } 1159 } 1160 if (any) { 1161 ParseNspFunction(); 1162 } 1163 cut = name_.find(':'); 1164 if (cut == 0) { 1165 xmlPullParserError_ = "illegal tag name: " + name_; 1166 } 1167 if (cut != std::string::npos) { 1168 prefix_ = name_.substr(0, cut); 1169 name_ = name_.substr(cut + 1); 1170 } 1171 namespace_ = GetNamespace(prefix_); 1172 return any; 1173 } 1174 ParseStartTagFuncDeal(bool throwOnResolveFailure)1175 bool XmlPullParser::ParseStartTagFuncDeal(bool throwOnResolveFailure) 1176 { 1177 std::string attrName = ParseName(); 1178 if (attrName.empty()) { 1179 return false; 1180 } 1181 int i = (attriCount_++) * 4; // 4: number of args 1182 attributes.resize(attributes.size() + 4); // 4: number of args 1183 attributes[i] = ""; 1184 attributes[i + 1] = ""; 1185 attributes[i + 2] = attrName; // 2: number of args 1186 SkipInvalidChar(); 1187 if (position_ >= max_ && !DealLength(1)) { 1188 xmlPullParserError_ = "UNEXPECTED_EOF"; 1189 return false; 1190 } 1191 if (strXml_[position_] == '=') { 1192 position_++; 1193 SkipInvalidChar(); 1194 if (position_ >= max_) { 1195 xmlPullParserError_ = "UNEXPECTED_EOF"; 1196 return false; 1197 } 1198 char delimiter = strXml_[position_]; 1199 if (delimiter == '\'' || delimiter == '"') { 1200 position_++; 1201 } else if (relaxed) { 1202 delimiter = ' '; 1203 } else { 1204 xmlPullParserError_ = "attr value delimiter missing!"; 1205 return false; 1206 } 1207 attributes[i + 3] = ParseTagValue(delimiter, true, // 3: number of args 1208 throwOnResolveFailure, TextEnum::ATTRI); // 3: number of args 1209 if (delimiter != ' ' && PriorDealChar() == delimiter) { 1210 position_++; 1211 } 1212 } else { 1213 attributes[i + 3] = attrName; // 3: number of args 1214 } 1215 return true; 1216 } 1217 ParseStartTagFunc(bool xmldecl,bool throwOnResolveFailure)1218 TagEnum XmlPullParser::ParseStartTagFunc(bool xmldecl, bool throwOnResolveFailure) 1219 { 1220 while (true) { 1221 SkipInvalidChar(); 1222 if (position_ >= max_ && DealLength(1)) { 1223 xmlPullParserError_ = "UNEXPECTED_EOF"; 1224 return TagEnum::ERROR; 1225 } 1226 unsigned char temp = strXml_[position_]; 1227 if (xmldecl) { 1228 if (temp == '?') { 1229 position_++; 1230 SkipChar('>'); 1231 return TagEnum::XML_DECLARATION; 1232 } 1233 } else { 1234 if (temp == '/') { 1235 bEndFlag_ = true; 1236 position_++; 1237 SkipInvalidChar(); 1238 SkipChar('>'); 1239 break; 1240 } else if (temp == '>') { 1241 position_++; 1242 break; 1243 } 1244 } 1245 bool bRecv = ParseStartTagFuncDeal(throwOnResolveFailure); 1246 if (!bRecv) { 1247 return TagEnum::ERROR; 1248 } 1249 } 1250 return TagEnum::OK; 1251 } 1252 ParseStartTag(bool xmldecl,bool throwOnResolveFailure)1253 TagEnum XmlPullParser::ParseStartTag(bool xmldecl, bool throwOnResolveFailure) 1254 { 1255 if (!xmldecl) { 1256 SkipChar('<'); 1257 } 1258 name_ = ParseName(); 1259 attriCount_ = 0; 1260 TagEnum bRecv = ParseStartTagFunc(xmldecl, throwOnResolveFailure); 1261 if (bRecv != TagEnum::OK) { 1262 return bRecv; 1263 } 1264 size_t sp = depth++ * 4; // 4: number of args 1265 elementStack_.resize(sp + 4); // 4: number of args 1266 elementStack_[sp + 3] = name_; // 3: number of args 1267 if (depth >= nspCounts_.size()) { 1268 nspCounts_.resize(depth + 4); // 4: number of args 1269 } 1270 nspCounts_[depth] = nspCounts_[depth - 1]; 1271 if (!bIgnoreNS_) { 1272 ParseNsp(); 1273 } else { 1274 namespace_ = ""; 1275 } 1276 if (defaultAttributes.size() != 0) { 1277 std::map<std::string, std::string> elementDefaultAttributes = defaultAttributes[name_]; 1278 if (elementDefaultAttributes.size() != 0) { 1279 for (std::map<std::string, std::string>::iterator iter = elementDefaultAttributes.begin(); 1280 iter != elementDefaultAttributes.end(); ++iter) { 1281 } 1282 } 1283 } 1284 elementStack_[sp] = namespace_; 1285 elementStack_[sp + 1] = prefix_; 1286 elementStack_[sp + 2] = name_; // 2: number of args 1287 return TagEnum::OK; 1288 } 1289 ParseDeclaration()1290 void XmlPullParser::ParseDeclaration() 1291 { 1292 if (bufferStartLine_ != 0 || bufferStartColumn_ != 0 || position_ != 0) { 1293 xmlPullParserError_ = "processing instructions must not start with xml"; 1294 } 1295 SkipText(tagText_.START_PROCESSING_INSTRUCTION); 1296 ParseStartTag(true, true); 1297 if (attriCount_ < 1 || attributes[2] != "version") { // 2: number of args 1298 xmlPullParserError_ = "version expected"; 1299 } 1300 version_ = attributes[3]; // 3: number of args 1301 size_t pos = 1; 1302 if (pos < attriCount_ && (attributes[2 + 4]) == "encoding") { // 4: number of args 2: number of args 1303 encoding_ = attributes[3 + 4]; // 3: number of args 4: number of args 1304 pos++; 1305 } 1306 if (pos < attriCount_ && (attributes[4 * pos + 2]) == "standalone") { // 4: number of args 2: number of args 1307 std::string st = attributes[3 + 4 * pos]; // 3: number of args 4: number of args 1308 if (st == "yes") { 1309 bAlone_ = true; 1310 } else if (st == "no") { 1311 bAlone_ = false; 1312 } else { 1313 xmlPullParserError_ = "illegal standalone value: " + st; 1314 } 1315 pos++; 1316 } 1317 if (pos != attriCount_) { 1318 xmlPullParserError_ = "unexpected attributes in XML declaration"; 1319 } 1320 bWhitespace_ = true; 1321 text_ = ""; 1322 } 1323 ParseEndTag()1324 bool XmlPullParser::ParseEndTag() 1325 { 1326 SkipChar('<'); 1327 SkipChar('/'); 1328 name_ = ParseName(); 1329 if (name_.empty()) { 1330 return false; 1331 } 1332 SkipInvalidChar(); 1333 SkipChar('>'); 1334 if (depth == 0) { 1335 xmlPullParserError_ = "read end tag " + name_ + " with no tags open"; 1336 type = TagEnum::COMMENT; 1337 return true; 1338 } 1339 size_t sp = (depth - 1) * 4; // 4: number of args 1340 if (name_ == elementStack_[sp + 3]) { // 3: number of args 1341 namespace_ = elementStack_[sp]; 1342 prefix_ = elementStack_[sp + 1]; 1343 name_ = elementStack_[sp + 2]; // 2: number of args 1344 } else if (!relaxed) { 1345 xmlPullParserError_ = "expected: /" + elementStack_[sp + 3] + " read: " + name_; // 3: number of args 1346 } 1347 return true; 1348 } 1349 ParseDelimiterInfo(std::string delimiter,bool returnText)1350 std::string XmlPullParser::ParseDelimiterInfo(std::string delimiter, bool returnText) 1351 { 1352 size_t start = position_; 1353 std::string result = ""; 1354 if (returnText && text_ != "") { 1355 result.append(text_); 1356 } 1357 bool bFlag = true; 1358 size_t delimLen = delimiter.length(); 1359 while (bFlag) { 1360 if (position_ + delimLen > max_) { 1361 xmlPullParserError_ = "Cannot find the '" + delimiter + "' in xml string."; 1362 return ""; 1363 } 1364 size_t i = 0; 1365 for (; i < delimLen; i++) { 1366 if (strXml_[position_ + i] != delimiter[i]) { 1367 position_++; 1368 break; 1369 } 1370 } 1371 if (i == delimLen) { 1372 bFlag = false; 1373 } 1374 } 1375 size_t end = position_; 1376 position_ += delimLen; 1377 if (!returnText) { 1378 return ""; 1379 } else { 1380 result.append(strXml_, start, end - start); 1381 return result; 1382 } 1383 } 1384 ParseDelimiter(bool returnText)1385 std::string XmlPullParser::ParseDelimiter(bool returnText) 1386 { 1387 int quote = PriorDealChar(); 1388 std::string delimiter; 1389 if (quote == '"') { 1390 delimiter = tagText_.DOUBLE_QUOTE; 1391 } else if (quote == '\'') { 1392 delimiter = tagText_.SINGLE_QUOTE; 1393 } else { 1394 xmlPullParserError_ = "Expected a quoted std::string "; 1395 } 1396 position_++; 1397 return ParseDelimiterInfo(delimiter, returnText); 1398 } 1399 ParserDoctInnerInfo(bool requireSystemName,bool assignFields)1400 bool XmlPullParser::ParserDoctInnerInfo(bool requireSystemName, bool assignFields) 1401 { 1402 SkipInvalidChar(); 1403 int c = PriorDealChar(); 1404 if (c == 'S') { 1405 SkipText(tagText_.SYSTEM); 1406 } else if (c == 'P') { 1407 SkipText(tagText_.PUBLIC); 1408 SkipInvalidChar(); 1409 if (assignFields) { 1410 pubInfo_ = ParseDelimiter(true); 1411 } else { 1412 ParseDelimiter(false); 1413 } 1414 } else { 1415 return false; 1416 } 1417 SkipInvalidChar(); 1418 if (!requireSystemName) { 1419 int delimiter = PriorDealChar(); 1420 if (delimiter != '"' && delimiter != '\'') { 1421 return true; // no system name! 1422 } 1423 } 1424 if (assignFields) { 1425 sysInfo_ = ParseDelimiter(true); 1426 } else { 1427 ParseDelimiter(false); 1428 } 1429 return true; 1430 } 1431 ParseComment(bool returnText)1432 void XmlPullParser::ParseComment(bool returnText) 1433 { 1434 SkipText(tagText_.START_COMMENT); 1435 if (relaxed) { 1436 std::string strTemp = ParseDelimiterInfo(tagText_.END_COMMENT, returnText); 1437 if (returnText) { 1438 text_ = strTemp; 1439 } 1440 } 1441 std::string commentText = ParseDelimiterInfo(tagText_.COMMENT_DOUBLE_DASH, returnText); 1442 if (PriorDealChar() != '>') { 1443 xmlPullParserError_ = "Comments may not contain -- "; 1444 } 1445 position_++; 1446 if (returnText) { 1447 text_ = commentText; 1448 } 1449 } 1450 ParseSpecText()1451 void XmlPullParser::ParseSpecText() 1452 { 1453 SkipInvalidChar(); 1454 int c = PriorDealChar(); 1455 if (c == '(') { 1456 int iDepth = 0; 1457 do { 1458 if (c == '(') { 1459 iDepth++; 1460 } else if (c == ')') { 1461 iDepth--; 1462 } else if (c == -1) { 1463 xmlPullParserError_ = "Unterminated element content spec "; 1464 } 1465 position_++; 1466 c = PriorDealChar(); 1467 } while (iDepth > 0); 1468 if (c == '*' || c == '?' || c == '+') { 1469 position_++; 1470 } 1471 } else if (c == tagText_.EMPTY[0]) { 1472 SkipText(tagText_.EMPTY); 1473 } else if (c == tagText_.ANY[0]) { 1474 SkipText(tagText_.ANY); 1475 } else { 1476 xmlPullParserError_ = "Expected element content spec "; 1477 } 1478 } 1479 ParseInnerEleDec()1480 void XmlPullParser::ParseInnerEleDec() 1481 { 1482 SkipText(tagText_.START_ELEMENT); 1483 SkipInvalidChar(); 1484 ParseName(); 1485 ParseSpecText(); 1486 SkipInvalidChar(); 1487 SkipChar('>'); 1488 } 1489 ParseInnerAttriDeclFunc(int & c)1490 void XmlPullParser::ParseInnerAttriDeclFunc(int &c) 1491 { 1492 if (c == '(') { 1493 position_++; 1494 while (true) { 1495 SkipInvalidChar(); 1496 ParseName(); 1497 SkipInvalidChar(); 1498 c = PriorDealChar(); 1499 if (c == ')') { 1500 position_++; 1501 break; 1502 } else if (c == '|') { 1503 position_++; 1504 } else { 1505 xmlPullParserError_ = "Malformed attribute type "; 1506 } 1507 } 1508 } else { 1509 ParseName(); 1510 } 1511 } 1512 ParseInnerAttriDecl()1513 void XmlPullParser::ParseInnerAttriDecl() 1514 { 1515 SkipText(tagText_.START_ATTLIST); 1516 SkipInvalidChar(); 1517 std::string elementName = ParseName(); 1518 while (true) { 1519 SkipInvalidChar(); 1520 int c = PriorDealChar(); 1521 if (c == '>') { 1522 position_++; 1523 return; 1524 } 1525 std::string attributeName = ParseName(); 1526 SkipInvalidChar(); 1527 if (position_ + 1 >= max_ && !DealLength(2)) { // 2: lengths 1528 xmlPullParserError_ = "Malformed attribute list "; 1529 } 1530 if (strXml_[position_] == tagText_.NOTATION[0] && strXml_[position_ + 1] == tagText_.NOTATION[1]) { 1531 SkipText(tagText_.NOTATION); 1532 SkipInvalidChar(); 1533 } 1534 c = PriorDealChar(); 1535 ParseInnerAttriDeclFunc(c); 1536 SkipInvalidChar(); 1537 c = PriorDealChar(); 1538 if (c == '#') { 1539 position_++; 1540 c = PriorDealChar(); 1541 if (c == 'R') { 1542 SkipText(tagText_.REQUIRED); 1543 } else if (c == 'I') { 1544 SkipText(tagText_.IMPLIED); 1545 } else if (c == 'F') { 1546 SkipText(tagText_.FIXED); 1547 } else { 1548 xmlPullParserError_ = "Malformed attribute type"; 1549 } 1550 SkipInvalidChar(); 1551 c = PriorDealChar(); 1552 } 1553 if (c == '"' || c == '\'') { 1554 position_++; 1555 std::string value = ParseTagValue(static_cast<char>(c), true, true, TextEnum::ATTRI); 1556 if (PriorDealChar() == c) { 1557 position_++; 1558 } 1559 } 1560 } 1561 } 1562 ParseEntityDecl()1563 void XmlPullParser::ParseEntityDecl() 1564 { 1565 SkipText(tagText_.START_ENTITY); 1566 bool generalEntity = true; 1567 SkipInvalidChar(); 1568 if (PriorDealChar() == '%') { 1569 generalEntity = false; 1570 position_++; 1571 SkipInvalidChar(); 1572 } 1573 std::string name = ParseName(); 1574 SkipInvalidChar(); 1575 int quote = PriorDealChar(); 1576 std::string entityValue; 1577 if (quote == '"' || quote == '\'') { 1578 position_++; 1579 entityValue = ParseTagValue(static_cast<char>(quote), true, false, TextEnum::ENTITY_DECL); 1580 if (PriorDealChar() == quote) { 1581 position_++; 1582 } 1583 } else if (ParserDoctInnerInfo(true, false)) { 1584 entityValue = ""; 1585 SkipInvalidChar(); 1586 if (PriorDealChar() == tagText_.NDATA[0]) { 1587 SkipText(tagText_.NDATA); 1588 SkipInvalidChar(); 1589 ParseName(); 1590 } 1591 } else { 1592 xmlPullParserError_ = "Expected entity value or external ID"; 1593 } 1594 if (generalEntity && bDocDecl) { 1595 documentEntities[name] = entityValue; 1596 } 1597 SkipInvalidChar(); 1598 SkipChar('>'); 1599 } 1600 ParseInneNotaDecl()1601 void XmlPullParser::ParseInneNotaDecl() 1602 { 1603 SkipText(tagText_.START_NOTATION); 1604 SkipInvalidChar(); 1605 ParseName(); 1606 if (!ParserDoctInnerInfo(false, false)) { 1607 xmlPullParserError_ = "Expected external ID or public ID for notation "; 1608 } 1609 SkipInvalidChar(); 1610 SkipChar('>'); 1611 } 1612 ReadInternalSubset()1613 void XmlPullParser::ReadInternalSubset() 1614 { 1615 SkipChar('['); 1616 while (true) { 1617 SkipInvalidChar(); 1618 if (PriorDealChar() == ']') { 1619 position_++; 1620 return; 1621 } 1622 TagEnum declarationType = ParseTagType(true); 1623 switch (declarationType) { 1624 case TagEnum::ELEMENTDECL: 1625 ParseInnerEleDec(); 1626 break; 1627 case TagEnum::ATTLISTDECL: 1628 ParseInnerAttriDecl(); 1629 break; 1630 case TagEnum::ENTITYDECL: 1631 ParseEntityDecl(); 1632 break; 1633 case TagEnum::NOTATIONDECL: 1634 ParseInneNotaDecl(); 1635 break; 1636 case TagEnum::INSTRUCTION: 1637 SkipText(tagText_.START_PROCESSING_INSTRUCTION); 1638 ParseDelimiterInfo(tagText_.END_PROCESSING_INSTRUCTION, false); 1639 break; 1640 case TagEnum::COMMENT: 1641 ParseComment(false); 1642 break; 1643 case TagEnum::PARAMETER_ENTITY_REF: 1644 xmlPullParserError_ = "Parameter entity references are not supported "; 1645 break; 1646 default: 1647 xmlPullParserError_ = "Unexpected token"; 1648 break; 1649 } 1650 } 1651 } 1652 ParseDoctype(bool saveDtdText)1653 void XmlPullParser::ParseDoctype(bool saveDtdText) 1654 { 1655 SkipText(tagText_.START_DOCTYPE); 1656 size_t startPosition = 0; 1657 if (saveDtdText) { 1658 keyInfo_ = ""; 1659 startPosition = position_; 1660 } 1661 SkipInvalidChar(); 1662 ParseName(); 1663 ParserDoctInnerInfo(true, true); 1664 SkipInvalidChar(); 1665 if (PriorDealChar() == '[') { 1666 ReadInternalSubset(); 1667 } 1668 SkipInvalidChar(); 1669 if (saveDtdText) { 1670 keyInfo_.append(strXml_, 0, position_); 1671 keyInfo_ = keyInfo_.substr(startPosition); 1672 text_ = keyInfo_; 1673 keyInfo_ = ""; 1674 } 1675 SkipChar('>'); 1676 } 1677 ParseText()1678 void XmlPullParser::ParseText() 1679 { 1680 text_ = ParseTagValue('<', true, false, TextEnum::TEXT); 1681 std::string strTemp = text_; 1682 Replace(strTemp, "\r", ""); 1683 Replace(strTemp, "\n", ""); 1684 Replace(strTemp, " ", ""); 1685 if ((depth == 0 && bWhitespace_) || strTemp.size() == 0) { 1686 type = TagEnum::WHITESPACE; 1687 } 1688 } 1689 ParseCdect()1690 void XmlPullParser::ParseCdect() 1691 { 1692 SkipText(tagText_.START_CDATA); 1693 text_ = ParseDelimiterInfo(tagText_.END_CDATA, true); 1694 } 1695 ParseOneTagFunc()1696 TagEnum XmlPullParser::ParseOneTagFunc() 1697 { 1698 switch (type) { 1699 case TagEnum::START_DOCUMENT: 1700 return type; 1701 case TagEnum::START_TAG: { 1702 if (ParseStartTag(false, false) == TagEnum::ERROR) { 1703 return TagEnum::ERROR; 1704 } 1705 return type;} 1706 case TagEnum::END_TAG: { 1707 if (ParseEndTag()) { 1708 return type; 1709 } 1710 return TagEnum::ERROR;} 1711 case TagEnum::END_DOCUMENT: 1712 return type; 1713 case TagEnum::ENTITY_REFERENCE: { 1714 std::string entityTextBuilder; 1715 ParseEntity(entityTextBuilder, true, false, TextEnum::TEXT); 1716 text_ = entityTextBuilder; 1717 return TagEnum::OK; 1718 } 1719 case TagEnum::TEXT: 1720 ParseText(); 1721 return TagEnum::OK; 1722 case TagEnum::CDSECT: 1723 ParseCdect(); 1724 return TagEnum::OK; 1725 case TagEnum::COMMENT: 1726 ParseComment(true); 1727 return TagEnum::OK; 1728 case TagEnum::INSTRUCTION: 1729 ParseInstruction(); 1730 return TagEnum::OK; 1731 case TagEnum::DOCDECL: 1732 ParseDoctype(true); 1733 return TagEnum::OK; 1734 default: 1735 xmlPullParserError_ = "Unexpected token"; 1736 return TagEnum::ERROR; 1737 } 1738 } 1739 ParseOneTag()1740 TagEnum XmlPullParser::ParseOneTag() 1741 { 1742 if (type == TagEnum::END_TAG) { 1743 depth--; 1744 } 1745 if (bEndFlag_) { 1746 bEndFlag_ = false; 1747 type = TagEnum::END_TAG; 1748 return type; 1749 } 1750 ParserPriorDeal(); 1751 while (true) { 1752 TagEnum typeTem = ParseOneTagFunc(); 1753 if (typeTem != TagEnum::OK) { 1754 return typeTem; 1755 } 1756 if (depth == 0 && (type == TagEnum::ENTITY_REFERENCE || type == TagEnum::TEXT || type == TagEnum::CDSECT)) { 1757 std::string errMsg = ""; 1758 if (!text_.empty()) { 1759 errMsg = ": " + text_; 1760 } 1761 xmlPullParserError_ = "Unexpected token" + errMsg; 1762 } 1763 if (type == TagEnum::DOCDECL && (!bDoctype_)) { 1764 ParseOneTag(); 1765 } 1766 return type; 1767 } 1768 } 1769 ParserPriorDeal()1770 void XmlPullParser::ParserPriorDeal() 1771 { 1772 type = ParseTagType(false); 1773 if (type == TagEnum::XML_DECLARATION) { 1774 ParseDeclaration(); 1775 type = ParseTagType(false); 1776 } 1777 text_ = ""; 1778 bWhitespace_ = true; 1779 prefix_ = ""; 1780 name_ = ""; 1781 namespace_ = ""; 1782 attriCount_ = 0; 1783 } 1784 ParseInstruction()1785 void XmlPullParser::ParseInstruction() 1786 { 1787 SkipText(tagText_.START_PROCESSING_INSTRUCTION); 1788 text_ = ParseDelimiterInfo(tagText_.END_PROCESSING_INSTRUCTION, true); 1789 } 1790 GetColumnNumber() const1791 int XmlPullParser::GetColumnNumber() const 1792 { 1793 size_t result = 0; 1794 for (size_t i = 0; i < position_; i++) { 1795 if (strXml_[i] == '\n') { 1796 result = 0; 1797 } else { 1798 result++; 1799 } 1800 } 1801 return result + 1; 1802 } 1803 GetDepth() const1804 int XmlPullParser::GetDepth() const 1805 { 1806 return depth; 1807 } 1808 GetLineNumber() const1809 int XmlPullParser::GetLineNumber() const 1810 { 1811 int result = bufferStartLine_; 1812 for (size_t i = 0; i < position_; i++) { 1813 if (strXml_[i] == '\n') { 1814 result++; 1815 } 1816 } 1817 return result + 1; 1818 } 1819 GetName() const1820 std::string XmlPullParser::GetName() const 1821 { 1822 return name_; 1823 } 1824 GetPrefix() const1825 std::string XmlPullParser::GetPrefix() const 1826 { 1827 return prefix_; 1828 } 1829 GetText() const1830 std::string XmlPullParser::GetText() const 1831 { 1832 if (type < TagEnum::TEXT || (type == TagEnum::ENTITY_REFERENCE && bUnresolved_)) { 1833 return ""; 1834 } else { 1835 return text_; 1836 } 1837 } 1838 IsEmptyElementTag() const1839 bool XmlPullParser::IsEmptyElementTag() const 1840 { 1841 return bEndFlag_; 1842 } 1843 GetAttributeCount() const1844 int XmlPullParser::GetAttributeCount() const 1845 { 1846 return attriCount_; 1847 } 1848 IsWhitespace() const1849 bool XmlPullParser::IsWhitespace() const 1850 { 1851 return bWhitespace_; 1852 } 1853 GetNamespace() const1854 std::string XmlPullParser::GetNamespace() const 1855 { 1856 return namespace_; 1857 } 1858 GetColumnNumber(napi_env env,napi_callback_info info)1859 napi_value XmlPullParser::ParseInfo::GetColumnNumber(napi_env env, napi_callback_info info) 1860 { 1861 napi_value thisVar = nullptr; 1862 napi_value mainVar = nullptr; 1863 NAPI_CALL(env, napi_get_cb_info(env, info, nullptr, nullptr, &thisVar, nullptr)); 1864 void *obj = nullptr; 1865 napi_get_named_property(env, thisVar, "MainInfo", &mainVar); 1866 NAPI_CALL(env, napi_unwrap(env, mainVar, &obj)); 1867 napi_value result = nullptr; 1868 if (obj != nullptr) { 1869 int temp = (reinterpret_cast<XmlPullParser *>(obj))->GetColumnNumber(); 1870 napi_create_int32(env, temp, &result); 1871 } 1872 return result; 1873 } 1874 GetDepth(napi_env env,napi_callback_info info)1875 napi_value XmlPullParser::ParseInfo::GetDepth(napi_env env, napi_callback_info info) 1876 { 1877 napi_value thisVar = nullptr; 1878 napi_value mainVar = nullptr; 1879 NAPI_CALL(env, napi_get_cb_info(env, info, nullptr, nullptr, &thisVar, nullptr)); 1880 void *obj = nullptr; 1881 napi_get_named_property(env, thisVar, "MainInfo", &mainVar); 1882 NAPI_CALL(env, napi_unwrap(env, mainVar, &obj)); 1883 napi_value result = nullptr; 1884 if (obj != nullptr) { 1885 int temp = (reinterpret_cast<XmlPullParser *>(obj))->GetDepth(); 1886 napi_create_int32(env, temp, &result); 1887 } 1888 return result; 1889 } 1890 GetLineNumber(napi_env env,napi_callback_info info)1891 napi_value XmlPullParser::ParseInfo::GetLineNumber(napi_env env, napi_callback_info info) 1892 { 1893 napi_value thisVar = nullptr; 1894 napi_value mainVar = nullptr; 1895 NAPI_CALL(env, napi_get_cb_info(env, info, nullptr, nullptr, &thisVar, nullptr)); 1896 void *obj = nullptr; 1897 napi_get_named_property(env, thisVar, "MainInfo", &mainVar); 1898 NAPI_CALL(env, napi_unwrap(env, mainVar, &obj)); 1899 napi_value result = nullptr; 1900 if (obj != nullptr) { 1901 int temp = (reinterpret_cast<XmlPullParser *>(obj))->GetLineNumber(); 1902 napi_create_int32(env, temp, &result); 1903 } 1904 return result; 1905 } 1906 GetName(napi_env env,napi_callback_info info)1907 napi_value XmlPullParser::ParseInfo::GetName(napi_env env, napi_callback_info info) 1908 { 1909 napi_value thisVar = nullptr; 1910 napi_value mainVar = nullptr; 1911 NAPI_CALL(env, napi_get_cb_info(env, info, nullptr, nullptr, &thisVar, nullptr)); 1912 void *obj = nullptr; 1913 napi_get_named_property(env, thisVar, "MainInfo", &mainVar); 1914 NAPI_CALL(env, napi_unwrap(env, mainVar, &obj)); 1915 napi_value result = nullptr; 1916 if (obj != nullptr) { 1917 std::string temp = (reinterpret_cast<XmlPullParser *>(obj))->GetName(); 1918 napi_create_string_utf8(env, temp.c_str(), temp.length(), &result); 1919 } 1920 return result; 1921 } 1922 GetNamespace(napi_env env,napi_callback_info info)1923 napi_value XmlPullParser::ParseInfo::GetNamespace(napi_env env, napi_callback_info info) 1924 { 1925 napi_value thisVar = nullptr; 1926 napi_value mainVar = nullptr; 1927 NAPI_CALL(env, napi_get_cb_info(env, info, nullptr, nullptr, &thisVar, nullptr)); 1928 void *obj = nullptr; 1929 napi_get_named_property(env, thisVar, "MainInfo", &mainVar); 1930 NAPI_CALL(env, napi_unwrap(env, mainVar, &obj)); 1931 napi_value result = nullptr; 1932 if (obj != nullptr) { 1933 std::string temp = (reinterpret_cast<XmlPullParser *>(obj))->GetNamespace(); 1934 napi_create_string_utf8(env, temp.c_str(), temp.length(), &result); 1935 } 1936 return result; 1937 } 1938 GetPrefix(napi_env env,napi_callback_info info)1939 napi_value XmlPullParser::ParseInfo::GetPrefix(napi_env env, napi_callback_info info) 1940 { 1941 napi_value thisVar = nullptr; 1942 napi_value mainVar = nullptr; 1943 NAPI_CALL(env, napi_get_cb_info(env, info, nullptr, nullptr, &thisVar, nullptr)); 1944 void *obj = nullptr; 1945 napi_get_named_property(env, thisVar, "MainInfo", &mainVar); 1946 NAPI_CALL(env, napi_unwrap(env, mainVar, &obj)); 1947 napi_value result = nullptr; 1948 if (obj != nullptr) { 1949 std::string temp = (reinterpret_cast<XmlPullParser *>(obj))->GetPrefix(); 1950 napi_create_string_utf8(env, temp.c_str(), temp.length(), &result); 1951 } 1952 return result; 1953 } 1954 GetText(napi_env env,napi_callback_info info)1955 napi_value XmlPullParser::ParseInfo::GetText(napi_env env, napi_callback_info info) 1956 { 1957 napi_value thisVar = nullptr; 1958 napi_value mainVar = nullptr; 1959 NAPI_CALL(env, napi_get_cb_info(env, info, nullptr, nullptr, &thisVar, nullptr)); 1960 void *obj = nullptr; 1961 napi_get_named_property(env, thisVar, "MainInfo", &mainVar); 1962 NAPI_CALL(env, napi_unwrap(env, mainVar, &obj)); 1963 napi_value result = nullptr; 1964 if (obj != nullptr) { 1965 std::string temp = (reinterpret_cast<XmlPullParser *>(obj))->GetText(); 1966 napi_create_string_utf8(env, temp.c_str(), temp.length(), &result); 1967 } 1968 return result; 1969 } 1970 IsEmptyElementTag(napi_env env,napi_callback_info info)1971 napi_value XmlPullParser::ParseInfo::IsEmptyElementTag(napi_env env, napi_callback_info info) 1972 { 1973 napi_value thisVar = nullptr; 1974 napi_value mainVar = nullptr; 1975 NAPI_CALL(env, napi_get_cb_info(env, info, nullptr, nullptr, &thisVar, nullptr)); 1976 void *obj = nullptr; 1977 napi_get_named_property(env, thisVar, "MainInfo", &mainVar); 1978 NAPI_CALL(env, napi_unwrap(env, mainVar, &obj)); 1979 napi_value result = nullptr; 1980 if (obj != nullptr) { 1981 bool temp = (reinterpret_cast<XmlPullParser *>(obj))->IsEmptyElementTag(); 1982 napi_get_boolean(env, temp, &result); 1983 } 1984 return result; 1985 } 1986 IsWhitespace(napi_env env,napi_callback_info info)1987 napi_value XmlPullParser::ParseInfo::IsWhitespace(napi_env env, napi_callback_info info) 1988 { 1989 napi_value thisVar = nullptr; 1990 napi_value mainVar = nullptr; 1991 NAPI_CALL(env, napi_get_cb_info(env, info, nullptr, nullptr, &thisVar, nullptr)); 1992 void *obj = nullptr; 1993 napi_get_named_property(env, thisVar, "MainInfo", &mainVar); 1994 NAPI_CALL(env, napi_unwrap(env, mainVar, &obj)); 1995 napi_value result = nullptr; 1996 if (obj != nullptr) { 1997 bool temp = (reinterpret_cast<XmlPullParser *>(obj))->IsWhitespace(); 1998 napi_get_boolean(env, temp, &result); 1999 } 2000 return result; 2001 } 2002 GetAttributeCount(napi_env env,napi_callback_info info)2003 napi_value XmlPullParser::ParseInfo::GetAttributeCount(napi_env env, napi_callback_info info) 2004 { 2005 napi_value thisVar = nullptr; 2006 napi_value mainVar = nullptr; 2007 NAPI_CALL(env, napi_get_cb_info(env, info, nullptr, nullptr, &thisVar, nullptr)); 2008 void *obj = nullptr; 2009 napi_get_named_property(env, thisVar, "MainInfo", &mainVar); 2010 NAPI_CALL(env, napi_unwrap(env, mainVar, &obj)); 2011 napi_value result = nullptr; 2012 if (obj != nullptr) { 2013 int temp = (reinterpret_cast<XmlPullParser *>(obj))->GetAttributeCount(); 2014 napi_create_int32(env, temp, &result); 2015 } 2016 return result; 2017 } 2018 } // namespace OHOS::Xml 2019 2020