• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2023 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 #include "xml_parser.h"
16 #include <algorithm>
17 
18 #include "config_policy_utils.h"
19 
20 namespace OHOS::Rosen {
LoadConfiguration(const char * fileDir)21 int32_t XMLParser::LoadConfiguration(const char* fileDir)
22 {
23     HGM_LOGI("XMLParser opening xml file");
24     xmlDocument_ = xmlReadFile(fileDir, nullptr, 0);
25     if (!xmlDocument_) {
26         HGM_LOGE("XMLParser xmlReadFile failed");
27         return XML_FILE_LOAD_FAIL;
28     }
29 
30     if (!mParsedData_) {
31         mParsedData_ = std::make_unique<PolicyConfigData>();
32     }
33 
34     return EXEC_SUCCESS;
35 }
36 
Parse()37 int32_t XMLParser::Parse()
38 {
39     HGM_LOGD("XMLParser Parse");
40     if (!xmlDocument_) {
41         HGM_LOGE("XMLParser xmlDocument_ is empty, should do LoadConfiguration first");
42         return HGM_ERROR;
43     }
44     xmlNode *root = xmlDocGetRootElement(xmlDocument_);
45     if (root == nullptr) {
46         HGM_LOGE("XMLParser xmlDocGetRootElement failed");
47         return XML_GET_ROOT_FAIL;
48     }
49 
50     if (ParseInternal(*root) == false) {
51         return XML_PARSE_INTERNAL_FAIL;
52     }
53     return EXEC_SUCCESS;
54 }
55 
Destroy()56 void XMLParser::Destroy()
57 {
58     HGM_LOGD("XMLParser Destroying the parser");
59     if (xmlDocument_ != nullptr) {
60         xmlFreeDoc(xmlDocument_);
61         xmlDocument_ = nullptr;
62     }
63 }
64 
GetHgmXmlNodeAsInt(xmlNode & node)65 int32_t XMLParser::GetHgmXmlNodeAsInt(xmlNode &node)
66 {
67     if (!xmlStrcmp(node.name, reinterpret_cast<const xmlChar*>("Param"))) {
68         return HGM_XML_PARAM;
69     }
70     if (!xmlStrcmp(node.name, reinterpret_cast<const xmlChar*>("Params"))) {
71         return HGM_XML_PARAMS;
72     }
73     HGM_LOGD("XMLParser failed to identify a xml node : %{public}s", node.name);
74     return HGM_XML_UNDEFINED;
75 }
76 
ParseInternal(xmlNode & node)77 bool XMLParser::ParseInternal(xmlNode &node)
78 {
79     HGM_LOGD("XMLParser parsing an internal node");
80     xmlNode *currNode = &node;
81     if (currNode->xmlChildrenNode == nullptr) {
82         HGM_LOGD("XMLParser stop parsing internal, no children nodes");
83         return false;
84     }
85     currNode = currNode->xmlChildrenNode;
86     int32_t parseSuccess = EXEC_SUCCESS;
87 
88     for (; currNode; currNode = currNode->next) {
89         if (currNode->type != XML_ELEMENT_NODE) {
90             continue;
91         }
92         if (parseSuccess != EXEC_SUCCESS) {
93             return false;
94         }
95         int xmlParamType = GetHgmXmlNodeAsInt(*currNode);
96         if (xmlParamType == HGM_XML_PARAM) {
97             parseSuccess = ParseParam(*currNode);
98         } else if (xmlParamType == HGM_XML_PARAMS) {
99             parseSuccess = ParseParams(*currNode);
100         }
101     }
102     return true;
103 }
104 
ParseParam(xmlNode & node)105 int32_t XMLParser::ParseParam(xmlNode &node)
106 {
107     HGM_LOGI("XMLParser parsing a parameter");
108     if (!mParsedData_) {
109         HGM_LOGE("XMLParser mParsedData_ is not initialized");
110         return HGM_ERROR;
111     }
112 
113     std::string paraName = ExtractPropertyValue("name", node);
114     if (paraName == "default_refreshrate_mode") {
115         HGM_LOGD("XMLParser parsing default_refreshrate_mode");
116         std::string mode = ExtractPropertyValue("value", node);
117         mParsedData_->defaultRefreshRateMode_ = mode;
118 
119         HGM_LOGI("HgmXMLParser ParseParam default_refreshrate_mode %{public}s",
120                  mParsedData_->defaultRefreshRateMode_.c_str());
121     }
122 
123     return EXEC_SUCCESS;
124 }
125 
ParseSubSequentParams(xmlNode & node,std::string & paraName)126 int32_t XMLParser::ParseSubSequentParams(xmlNode &node, std::string &paraName)
127 {
128     int32_t setResult = EXEC_SUCCESS;
129 
130     if (paraName == "additional_touch_rate_config") {
131         ParseAppBufferList(node);
132     } else if (paraName == "refreshRate_strategy_config") {
133         setResult = ParseStrategyConfig(node);
134     } else if (paraName == "refreshRate_virtual_display_config") {
135         if (ExtractPropertyValue("switch", node) == "1") {
136             setResult = ParseSimplex(node, mParsedData_->virtualDisplayConfigs_, "strategy");
137             mParsedData_->virtualDisplaySwitch_ = true;
138         } else {
139             mParsedData_->virtualDisplayConfigs_.clear();
140             mParsedData_->virtualDisplaySwitch_ = false;
141         }
142     } else if (paraName == "safe_vote") {
143         // "1": enable
144         mParsedData_->safeVoteEnabled = ExtractPropertyValue("switch", node) == "1";
145     } else if (paraName == "screen_strategy_config") {
146         setResult = ParseSimplex(node, mParsedData_->screenStrategyConfigs_, "type");
147     } else if (paraName == "screen_config") {
148         setResult = ParseScreenConfig(node);
149     } else if (paraName == "rs_video_frame_rate_vote_config") {
150         setResult = ParseVideoFrameVoteConfig(node);
151     } else if (paraName == "source_tuning_for_yuv420") {
152         setResult = ParseSimplex(node, mParsedData_->sourceTuningConfig_);
153     } else {
154         setResult = EXEC_SUCCESS;
155     }
156 
157     return setResult;
158 }
159 
ParseParams(xmlNode & node)160 int32_t XMLParser::ParseParams(xmlNode &node)
161 {
162     std::string paraName = ExtractPropertyValue("name", node);
163     if (paraName.empty()) {
164         return XML_PARSE_INTERNAL_FAIL;
165     }
166     if (!mParsedData_) {
167         HGM_LOGE("XMLParser mParsedData_ is not initialized");
168         return HGM_ERROR;
169     }
170 
171     int32_t setResult = EXEC_SUCCESS;
172     if (paraName == "refresh_rate_4settings") {
173         std::unordered_map<std::string, std::string> refreshRateForSettings;
174         setResult = ParseSimplex(node, refreshRateForSettings);
175         if (setResult != EXEC_SUCCESS) {
176             mParsedData_->xmlCompatibleMode_ = true;
177             setResult = ParseSimplex(node, refreshRateForSettings, "id");
178         }
179         mParsedData_->refreshRateForSettings_.clear();
180         for (auto &[name, id]: refreshRateForSettings) {
181             if (IsNumber(name) && IsNumber(id)) {
182                 mParsedData_->refreshRateForSettings_.emplace_back(
183                     std::pair<int32_t, int32_t>(std::stoi(name), std::stoi(id)));
184             }
185         }
186         std::sort(mParsedData_->refreshRateForSettings_.begin(), mParsedData_->refreshRateForSettings_.end(),
187             [=] (auto rateId0, auto rateId1) { return rateId0.first < rateId1.first; });
188     } else {
189         setResult = ParseSubSequentParams(node, paraName);
190     }
191 
192     if (setResult != EXEC_SUCCESS) {
193         HGM_LOGI("XMLParser failed to ParseParams %{public}s", paraName.c_str());
194     }
195     return EXEC_SUCCESS;
196 }
197 
ParseVideoFrameVoteConfig(xmlNode & node)198 int32_t XMLParser::ParseVideoFrameVoteConfig(xmlNode &node)
199 {
200     mParsedData_->videoFrameRateVoteSwitch_ = ExtractPropertyValue("switch", node) == "1";
201     return ParseSimplex(node, mParsedData_->videoFrameRateList_);
202 }
203 
ParseStrategyConfig(xmlNode & node)204 int32_t XMLParser::ParseStrategyConfig(xmlNode &node)
205 {
206     HGM_LOGD("XMLParser parsing strategyConfig");
207     xmlNode *currNode = &node;
208     if (currNode->xmlChildrenNode == nullptr) {
209         HGM_LOGD("XMLParser stop parsing strategyConfig, no children nodes");
210         return HGM_ERROR;
211     }
212 
213     // re-parse
214     mParsedData_->strategyConfigs_.clear();
215     currNode = currNode->xmlChildrenNode;
216     for (; currNode; currNode = currNode->next) {
217         if (currNode->type != XML_ELEMENT_NODE) {
218             continue;
219         }
220 
221         auto name = ExtractPropertyValue("name", *currNode);
222         auto min = ExtractPropertyValue("min", *currNode);
223         auto max = ExtractPropertyValue("max", *currNode);
224         auto dynamicMode = ExtractPropertyValue("dynamicMode", *currNode);
225         auto isFactor = ExtractPropertyValue("isFactor", *currNode) == "1"; // 1:true, other:false
226         auto drawMin = ExtractPropertyValue("drawMin", *currNode);
227         auto drawMax = ExtractPropertyValue("drawMax", *currNode);
228         auto down = ExtractPropertyValue("down", *currNode);
229         if (!IsNumber(min) || !IsNumber(max) || !IsNumber(dynamicMode)) {
230             return HGM_ERROR;
231         }
232 
233         PolicyConfigData::StrategyConfig strategy;
234         strategy.min = std::stoi(min);
235         strategy.max = std::stoi(max);
236         strategy.dynamicMode = static_cast<DynamicModeType>(std::stoi(dynamicMode));
237         strategy.isFactor = isFactor;
238         strategy.drawMin = IsNumber(drawMin) ? std::stoi(drawMin) : 0;
239         strategy.drawMax = IsNumber(drawMax) ? std::stoi(drawMax) : 0;
240         strategy.down = IsNumber(down) ? std::stoi(down) : strategy.max;
241         ParseBufferStrategyList(*currNode, strategy);
242         mParsedData_->strategyConfigs_[name] = strategy;
243         HGM_LOGI("HgmXMLParser ParseStrategyConfig name=%{public}s min=%{public}d drawMin=%{public}d",
244                  name.c_str(), mParsedData_->strategyConfigs_[name].min, mParsedData_->strategyConfigs_[name].drawMin);
245     }
246 
247     return EXEC_SUCCESS;
248 }
249 
ParseAppBufferList(xmlNode & node)250 void XMLParser::ParseAppBufferList(xmlNode &node)
251 {
252     HGM_LOGD("XMLParser parsing ParseAppBufferList");
253     xmlNode *currNode = &node;
254     if (currNode->xmlChildrenNode == nullptr) {
255         HGM_LOGD("XMLParser stop parsing ParseAppBufferList, no children nodes");
256         return;
257     }
258 
259     mParsedData_->appBufferList_.clear();
260     currNode = currNode->xmlChildrenNode;
261     for (; currNode; currNode = currNode->next) {
262         if (currNode->type != XML_ELEMENT_NODE) {
263             continue;
264         }
265         auto name = ExtractPropertyValue("name", *currNode);
266         mParsedData_->appBufferList_.push_back(name);
267     }
268 }
269 
ParseBufferStrategyList(xmlNode & node,PolicyConfigData::StrategyConfig & strategy)270 void XMLParser::ParseBufferStrategyList(xmlNode &node, PolicyConfigData::StrategyConfig &strategy)
271 {
272     if (mParsedData_->appBufferList_.empty()) {
273         return;
274     }
275     std::unordered_map<std::string, std::string> config;
276     for (auto &name : mParsedData_->appBufferList_) {
277         auto fps = ExtractPropertyValue(name, node);
278         if (IsNumber(fps)) {
279             config.insert(make_pair(name, fps));
280         }
281     }
282     if (config.empty()) {
283         return;
284     }
285     for (auto &it : config) {
286         if (std::stoi(it.second) == 0) {
287             strategy.appBufferBlackList.push_back(it.first);
288         } else {
289             strategy.appBufferList.push_back(make_pair(it.first, std::stoi(it.second)));
290         }
291     }
292     if (strategy.appBufferList.empty()) {
293         return;
294     }
295     std::sort(strategy.appBufferList.begin(), strategy.appBufferList.end(),
296         [](const std::pair<std::string, int32_t>& a, const std::pair<std::string, int32_t>& b) {
297         return a.second > b.second;
298     });
299 
300     return;
301 }
302 
ParseScreenConfig(xmlNode & node)303 int32_t XMLParser::ParseScreenConfig(xmlNode &node)
304 {
305     HGM_LOGD("XMLParser parsing screenConfig");
306     xmlNode *currNode = &node;
307     if (currNode->xmlChildrenNode == nullptr) {
308         HGM_LOGD("XMLParser stop parsing screenConfig, no children nodes");
309         return HGM_ERROR;
310     }
311 
312     auto type = ExtractPropertyValue("type", *currNode);
313     PolicyConfigData::ScreenConfig screenConfig;
314     currNode = currNode->xmlChildrenNode;
315     for (; currNode; currNode = currNode->next) {
316         if (currNode->type != XML_ELEMENT_NODE) {
317             continue;
318         }
319         PolicyConfigData::ScreenSetting screenSetting;
320         auto id = ExtractPropertyValue("id", *currNode);
321         screenSetting.strategy = ExtractPropertyValue("strategy", *currNode);
322         for (xmlNode *thresholdNode = currNode->xmlChildrenNode; thresholdNode; thresholdNode = thresholdNode->next) {
323             ParseSubScreenConfig(*thresholdNode, screenSetting);
324         }
325         screenConfig[id] = screenSetting;
326         HGM_LOGI("HgmXMLParser ParseScreenConfig id=%{public}s", id.c_str());
327     }
328     mParsedData_->screenConfigs_[type] = screenConfig;
329     return EXEC_SUCCESS;
330 }
331 
ParseSubScreenConfig(xmlNode & node,PolicyConfigData::ScreenSetting & screenSetting)332 int32_t XMLParser::ParseSubScreenConfig(xmlNode &node, PolicyConfigData::ScreenSetting& screenSetting)
333 {
334     xmlNode *thresholdNode = &node;
335     if (thresholdNode->type != XML_ELEMENT_NODE) {
336         return HGM_ERROR;
337     }
338     auto name = ExtractPropertyValue("name", *thresholdNode);
339     int32_t setResult = EXEC_SUCCESS;
340     if (name == "LTPO_config") {
341         setResult = ParseSimplex(*thresholdNode, screenSetting.ltpoConfig);
342     } else if (name == "property_animation_dynamic_settings") {
343         setResult = ParserDynamicSetting(*thresholdNode, screenSetting.animationDynamicSettings);
344     } else if (name == "ace_scene_dynamic_settings") {
345         setResult = ParserDynamicSetting(*thresholdNode, screenSetting.aceSceneDynamicSettings);
346     } else if (name == "scene_list") {
347         setResult = ParseSceneList(*thresholdNode, screenSetting.sceneList);
348     } else if (name == "game_scene_list") {
349         setResult = ParseSimplex(*thresholdNode, screenSetting.gameSceneList);
350     } else if (name == "anco_scene_list") {
351         setResult = ParseSceneList(*thresholdNode, screenSetting.ancoSceneList);
352     } else if (name == "app_list") {
353         ParseMultiAppStrategy(*thresholdNode, screenSetting);
354     } else if (name == "app_types") {
355         setResult = ParseAppTypes(*thresholdNode, screenSetting.appTypes);
356     } else if (name == "rs_animation_power_config") {
357         setResult = ParseSimplex(*thresholdNode, screenSetting.animationPowerConfig);
358     } else if (name == "ui_power_config") {
359         setResult = ParseSimplex(*thresholdNode, screenSetting.uiPowerConfig);
360     } else {
361         setResult = EXEC_SUCCESS;
362     }
363 
364     if (setResult != EXEC_SUCCESS) {
365         HGM_LOGI("XMLParser failed to ParseScreenConfig %{public}s", name.c_str());
366     }
367     return setResult;
368 }
369 
ParseSimplex(xmlNode & node,std::unordered_map<std::string,std::string> & config,const std::string & valueName,const std::string & keyName)370 int32_t XMLParser::ParseSimplex(xmlNode &node, std::unordered_map<std::string, std::string> &config,
371                                 const std::string &valueName, const std::string &keyName)
372 {
373     HGM_LOGD("XMLParser parsing simplex");
374     xmlNode *currNode = &node;
375     if (currNode->xmlChildrenNode == nullptr) {
376         HGM_LOGD("XMLParser stop parsing simplex, no children nodes");
377         return HGM_ERROR;
378     }
379 
380     // re-parse
381     config.clear();
382     currNode = currNode->xmlChildrenNode;
383     for (; currNode; currNode = currNode->next) {
384         if (currNode->type != XML_ELEMENT_NODE) {
385             continue;
386         }
387 
388         auto key = ExtractPropertyValue(keyName, *currNode);
389         auto value = ExtractPropertyValue(valueName, *currNode);
390         if (key.empty() || value.empty()) {
391             return XML_PARSE_INTERNAL_FAIL;
392         }
393         config[key] = value;
394 
395         HGM_LOGI("HgmXMLParser ParseSimplex %{public}s=%{public}s %{public}s=%{public}s",
396                  keyName.c_str(), key.c_str(), valueName.c_str(), config[key].c_str());
397     }
398 
399     return EXEC_SUCCESS;
400 }
401 
ParserDynamicSetting(xmlNode & node,PolicyConfigData::DynamicSettingMap & dynamicSettingMap)402 int32_t XMLParser::ParserDynamicSetting(xmlNode &node, PolicyConfigData::DynamicSettingMap &dynamicSettingMap)
403 {
404     HGM_LOGD("XMLParser parsing dynamicSetting");
405     xmlNode *currNode = &node;
406     if (currNode->xmlChildrenNode == nullptr) {
407         HGM_LOGD("XMLParser stop parsing dynamicSetting, no children nodes");
408         return HGM_ERROR;
409     }
410 
411     // re-parse
412     dynamicSettingMap.clear();
413     currNode = currNode->xmlChildrenNode;
414     for (; currNode; currNode = currNode->next) {
415         auto dynamicSettingType = ExtractPropertyValue("name", *currNode);
416         PolicyConfigData::DynamicSetting dynamicSetting;
417         dynamicSettingMap[dynamicSettingType] = dynamicSetting;
418         for (xmlNode *thresholdNode = currNode->xmlChildrenNode; thresholdNode; thresholdNode = thresholdNode->next) {
419             if (thresholdNode->type != XML_ELEMENT_NODE) {
420                 continue;
421             }
422             auto name = ExtractPropertyValue("name", *thresholdNode);
423             auto min = ExtractPropertyValue("min", *thresholdNode);
424             auto max = ExtractPropertyValue("max", *thresholdNode);
425             auto preferred_fps = ExtractPropertyValue("preferred_fps", *thresholdNode);
426             if (!IsNumber(min) || !IsNumber(max) || !IsNumber(preferred_fps)) {
427                 dynamicSettingMap[dynamicSettingType].clear();
428                 break;
429             }
430             PolicyConfigData::DynamicConfig dynamicConfig;
431             dynamicConfig.min = std::stoi(min);
432             dynamicConfig.max = std::stoi(max);
433             dynamicConfig.preferred_fps = std::stoi(preferred_fps);
434             dynamicSettingMap[dynamicSettingType][name] = dynamicConfig;
435 
436             HGM_LOGI("HgmXMLParser ParserDynamicSetting dynamicType=%{public}s name=%{public}s min=%{public}d",
437                      dynamicSettingType.c_str(), name.c_str(), dynamicSettingMap[dynamicSettingType][name].min);
438         }
439     }
440     return EXEC_SUCCESS;
441 }
442 
ParseSceneList(xmlNode & node,PolicyConfigData::SceneConfigMap & sceneList)443 int32_t XMLParser::ParseSceneList(xmlNode &node, PolicyConfigData::SceneConfigMap &sceneList)
444 {
445     HGM_LOGD("XMLParser parsing sceneList");
446     xmlNode *currNode = &node;
447     if (currNode->xmlChildrenNode == nullptr) {
448         HGM_LOGD("XMLParser stop parsing sceneList, no children nodes");
449         return HGM_ERROR;
450     }
451 
452     // re-parse
453     sceneList.clear();
454     currNode = currNode->xmlChildrenNode;
455     for (; currNode; currNode = currNode->next) {
456         if (currNode->type != XML_ELEMENT_NODE) {
457             continue;
458         }
459         PolicyConfigData::SceneConfig sceneConfig;
460         auto name = ExtractPropertyValue("name", *currNode);
461         sceneConfig.strategy = ExtractPropertyValue("strategy", *currNode);
462         sceneConfig.priority = ExtractPropertyValue("priority", *currNode);
463 
464         sceneList[name] = sceneConfig;
465         HGM_LOGI("HgmXMLParser ParseSceneList name=%{public}s strategy=%{public}s priority=%{public}s",
466                  name.c_str(), sceneList[name].strategy.c_str(), sceneList[name].priority.c_str());
467     }
468 
469     return EXEC_SUCCESS;
470 }
471 
ParseMultiAppStrategy(xmlNode & node,PolicyConfigData::ScreenSetting & screenSetting)472 int32_t XMLParser::ParseMultiAppStrategy(xmlNode &node, PolicyConfigData::ScreenSetting &screenSetting)
473 {
474     auto multiAppStrategy = ExtractPropertyValue("multi_app_strategy", node);
475     if (multiAppStrategy == "focus") {
476         screenSetting.multiAppStrategyType = MultiAppStrategyType::FOLLOW_FOCUS;
477     } else if (multiAppStrategy.find("strategy_") != std::string::npos) {
478         screenSetting.multiAppStrategyType = MultiAppStrategyType::USE_STRATEGY_NUM;
479         screenSetting.multiAppStrategyName = multiAppStrategy.substr(
480             std::string("strategy_").size(), multiAppStrategy.size());
481     } else {
482         screenSetting.multiAppStrategyType = MultiAppStrategyType::USE_MAX;
483     }
484     return ParseSimplex(node, screenSetting.appList, "strategy");
485 }
486 
487 
ParseAppTypes(xmlNode & node,std::unordered_map<int32_t,std::string> & appTypes)488 int32_t XMLParser::ParseAppTypes(xmlNode &node, std::unordered_map<int32_t, std::string> &appTypes)
489 {
490     HGM_LOGD("XMLParser parsing appTypes");
491     xmlNode *currNode = &node;
492     if (currNode->xmlChildrenNode == nullptr) {
493         HGM_LOGD("XMLParser stop parsing appTypes, no children nodes");
494         return HGM_ERROR;
495     }
496 
497     // re-parse
498     appTypes.clear();
499     currNode = currNode->xmlChildrenNode;
500     for (; currNode; currNode = currNode->next) {
501         if (currNode->type != XML_ELEMENT_NODE) {
502             continue;
503         }
504         auto name = ExtractPropertyValue("name", *currNode);
505         if (!IsNumber(name)) {
506             continue;
507         }
508         auto strategy = ExtractPropertyValue("strategy", *currNode);
509         appTypes[std::stoi(name)] = strategy;
510         HGM_LOGI("HgmXMLParser ParseAppTypes name=%{public}s strategy=%{public}s", name.c_str(), strategy.c_str());
511     }
512 
513     return EXEC_SUCCESS;
514 }
515 
ExtractPropertyValue(const std::string & propName,xmlNode & node)516 std::string XMLParser::ExtractPropertyValue(const std::string &propName, xmlNode &node)
517 {
518     HGM_LOGD("XMLParser extracting value : %{public}s", propName.c_str());
519     std::string propValue = "";
520     xmlChar *tempValue = nullptr;
521 
522     if (xmlHasProp(&node, reinterpret_cast<const xmlChar*>(propName.c_str()))) {
523         tempValue = xmlGetProp(&node, reinterpret_cast<const xmlChar*>(propName.c_str()));
524     }
525 
526     if (tempValue != nullptr) {
527         HGM_LOGD("XMLParser not aempty tempValue");
528         propValue = reinterpret_cast<const char*>(tempValue);
529         xmlFree(tempValue);
530         tempValue = nullptr;
531     }
532 
533     return propValue;
534 }
535 
IsNumber(const std::string & str)536 bool XMLParser::IsNumber(const std::string& str)
537 {
538     if (str.length() == 0) {
539         return false;
540     }
541     auto number = static_cast<uint32_t>(std::count_if(str.begin(), str.end(), [](unsigned char c) {
542         return std::isdigit(c);
543     }));
544     return number == str.length() || (str.compare(0, 1, "-") == 0 && number == str.length() - 1);
545 }
546 
547 } // namespace OHOS::Rosen