• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2025 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_base.h"
16 
17 #include <algorithm>
18 #include "graphic_feature_param_manager.h"
19 
20 namespace OHOS::Rosen {
21 namespace {
22 constexpr uint32_t XML_STRING_MAX_LENGTH = 20;
23 }
24 
Destroy()25 void XMLParserBase::Destroy()
26 {
27     RS_LOGD("XMLParserBase Destroying the parser");
28     if (xmlSysDocument_ != nullptr) {
29         xmlFreeDoc(xmlSysDocument_);
30         xmlSysDocument_ = nullptr;
31     }
32     if (xmlProdDocument_ != nullptr) {
33         xmlFreeDoc(xmlProdDocument_);
34         xmlProdDocument_ = nullptr;
35     }
36 }
37 
LoadSysConfiguration(const std::string & fileDir)38 int32_t XMLParserBase::LoadSysConfiguration(const std::string& fileDir)
39 {
40     for (const std::string& configPath : sysPaths_) {
41         std::string graphicFilePath = configPath + fileDir;
42         xmlSysDocument_ = xmlReadFile(graphicFilePath.c_str(), nullptr, 0);
43         if (xmlSysDocument_ != nullptr) {
44             RS_LOGD("XMLParserBase success to get sys graphic config: %{public}s", graphicFilePath.c_str());
45             break;
46         }
47     }
48     if (!xmlSysDocument_) {
49         RS_LOGE("XMLParserBase read system file failed");
50         return PARSE_SYS_FILE_LOAD_FAIL;
51     }
52     return PARSE_EXEC_SUCCESS;
53 }
54 
LoadProdConfiguration(const std::string & fileDir)55 void XMLParserBase::LoadProdConfiguration(const std::string& fileDir)
56 {
57     std::string graphicFilePath = prodPath_ + fileDir;
58     xmlProdDocument_ = xmlReadFile(graphicFilePath.c_str(), nullptr, 0);
59     if (!xmlProdDocument_) {
60         RS_LOGD("XMLParserBase not have prod graphic config: %{public}s", graphicFilePath.c_str());
61     }
62 }
63 
LoadGraphicConfiguration(const std::string & fileDir)64 int32_t XMLParserBase::LoadGraphicConfiguration(const std::string& fileDir)
65 {
66     RS_LOGI("XMLParserBase opening xml file");
67     // System base config file read
68     if (LoadSysConfiguration(fileDir) != PARSE_EXEC_SUCCESS) {
69         return PARSE_SYS_FILE_LOAD_FAIL;
70     }
71     // For different feature settings in variant products
72     LoadProdConfiguration(fileDir);
73     return PARSE_EXEC_SUCCESS;
74 }
75 
ParseSysDoc()76 int32_t XMLParserBase::ParseSysDoc()
77 {
78     RS_LOGI("XMLParserBase Parse SysDoc Start");
79     if (!xmlSysDocument_) {
80         RS_LOGE("XMLParserBase xmlSysDocument_ is empty, should do LoadGraphicConfiguration first");
81         return PARSE_SYS_FILE_LOAD_FAIL;
82     }
83     xmlNode *root = xmlDocGetRootElement(xmlSysDocument_);
84     if (root == nullptr) {
85         RS_LOGE("XMLParserBase xmlDocGetRootElement failed");
86         return PARSE_GET_ROOT_FAIL;
87     }
88 
89     if (ParseInternal(*root) == false) {
90         return PARSE_INTERNAL_FAIL;
91     }
92     return PARSE_EXEC_SUCCESS;
93 }
94 
ParseProdDoc()95 int32_t XMLParserBase::ParseProdDoc()
96 {
97     RS_LOGI("XMLParserBase Parse ProdDoc Start");
98     if (!xmlProdDocument_) {
99         RS_LOGD("XMLParserBase xmlProdDocument_ is empty, check if need product config first");
100         return PARSE_PROD_FILE_LOAD_FAIL;
101     }
102     xmlNode *root = xmlDocGetRootElement(xmlProdDocument_);
103     if (root == nullptr) {
104         RS_LOGE("XMLParserBase xmlDocGetRootElement failed");
105         return PARSE_GET_ROOT_FAIL;
106     }
107 
108     if (ParseInternal(*root) == false) {
109         return PARSE_INTERNAL_FAIL;
110     }
111     return PARSE_EXEC_SUCCESS;
112 }
113 
ParseInternal(xmlNode & node)114 bool XMLParserBase::ParseInternal(xmlNode &node)
115 {
116     RS_LOGI("XMLParserBase ParseInternal Start");
117     xmlNode *currNode = &node;
118     if (currNode->xmlChildrenNode == nullptr) {
119         RS_LOGD("XMLParserBase stop parsing internal, no children nodes");
120         return false;
121     }
122     currNode = currNode->xmlChildrenNode;
123     int32_t parseSuccess = PARSE_EXEC_SUCCESS;
124 
125     for (; currNode; currNode = currNode->next) {
126         if (currNode->type != XML_ELEMENT_NODE) {
127             continue;
128         }
129 
130         std::string featureName = ExtractPropertyValue("name", *currNode);
131         RS_LOGI("XMLParserBase featureName is: %{public}s", featureName.c_str());
132         if (featureName == "") {
133             RS_LOGE("XMLParserBase featureName is empty");
134             continue;
135         }
136         auto parseMap = GraphicFeatureParamManager::GetInstance().featureParseMap_;
137         auto featureMap = GraphicFeatureParamManager::GetInstance().featureParamMap_;
138         auto iter = parseMap.find(featureName);
139         if (iter != parseMap.end()) {
140             auto featureObj = iter->second;
141             parseSuccess = featureObj->ParseFeatureParam(featureMap, *currNode);
142             if (parseSuccess != PARSE_EXEC_SUCCESS) {
143                 RS_LOGE("XMLParserBase current feature : %{public}s parse fail", featureName.c_str());
144                 continue;
145             }
146         } else {
147             RS_LOGD("XMLParserBase featureMap cannot find feature %{public}s", featureName.c_str());
148         }
149     }
150     return true;
151 }
152 
ExtractPropertyValue(const std::string & propName,xmlNode & node)153 std::string XMLParserBase::ExtractPropertyValue(const std::string &propName, xmlNode &node)
154 {
155     RS_LOGD("XMLParserBase extracting value : %{public}s", propName.c_str());
156     std::string propValue = "";
157     xmlChar *tempValue = nullptr;
158 
159     if (xmlHasProp(&node, reinterpret_cast<const xmlChar*>(propName.c_str()))) {
160         tempValue = xmlGetProp(&node, reinterpret_cast<const xmlChar*>(propName.c_str()));
161     }
162 
163     if (tempValue != nullptr) {
164         RS_LOGD("XMLParserBase not a empty tempValue");
165         propValue = reinterpret_cast<const char*>(tempValue);
166         xmlFree(tempValue);
167         tempValue = nullptr;
168     }
169 
170     return propValue;
171 }
172 
GetXmlNodeAsInt(xmlNode & node)173 int32_t XMLParserBase::GetXmlNodeAsInt(xmlNode &node)
174 {
175     if (!xmlStrcmp(node.name, reinterpret_cast<const xmlChar*>("FeatureSwitch"))) {
176         return PARSE_XML_FEATURE_SWITCH;
177     }
178     if (!xmlStrcmp(node.name, reinterpret_cast<const xmlChar*>("FeatureSingleParam"))) {
179         return PARSE_XML_FEATURE_SINGLEPARAM;
180     }
181     if (!xmlStrcmp(node.name, reinterpret_cast<const xmlChar*>("FeatureMultiParam"))) {
182         return PARSE_XML_FEATURE_MULTIPARAM;
183     }
184     RS_LOGD("XMLParserBase failed to identify a xml node : %{public}s", node.name);
185     return PARSE_XML_UNDEFINED;
186 }
187 
IsNumber(const std::string & str)188 bool XMLParserBase::IsNumber(const std::string& str)
189 {
190     if (str.length() == 0 || str.length() > XML_STRING_MAX_LENGTH) {
191         return false;
192     }
193     auto number = static_cast<uint32_t>(std::count_if(str.begin(), str.end(), [](unsigned char c) {
194         return std::isdigit(c);
195     }));
196     return number == str.length() || (str.compare(0, 1, "-") == 0 && number == str.length() - 1);
197 }
198 
ParseFeatureSwitch(std::string val)199 bool XMLParserBase::ParseFeatureSwitch(std::string val)
200 {
201     return val == "true";
202 }
203 } // namespace OHOS::Rosen
204