• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 "config_reader.h"
17 #include "res_sched_log.h"
18 
19 using namespace std;
20 
21 namespace OHOS {
22 namespace ResourceSchedule {
23 namespace {
24 constexpr auto XML_TAG_RES_SCHED = "ressched";
25 constexpr auto XML_TAG_PLUGIN = "plugin";
26 constexpr auto XML_TAG_CONFIG = "config";
27 constexpr auto XML_TAG_ITEM = "item";
28 constexpr auto XML_ATTR_NAME = "name";
29 }
30 
IsInvalidNode(const xmlNode & currNode)31 bool ConfigReader::IsInvalidNode(const xmlNode& currNode)
32 {
33     if (!currNode.name || currNode.type == XML_COMMENT_NODE) {
34         return true;
35     }
36     return false;
37 }
38 
ParseProperties(const xmlNode & currNode,map<string,string> & properties)39 void ConfigReader::ParseProperties(const xmlNode& currNode, map<string, string>& properties)
40 {
41     auto attrs = currNode.properties;
42     xmlChar *value;
43     for (; attrs; attrs = attrs->next) {
44         auto name = attrs->name;
45         if (!name) {
46             RESSCHED_LOGW("ConfigReader::ParseProperties name null!");
47             continue;
48         }
49         value = xmlGetProp(&currNode, name);
50         if (!value) {
51             RESSCHED_LOGW("ConfigReader::ParseProperties name(%{public}s) value null!", name);
52             continue;
53         }
54         properties[reinterpret_cast<const char*>(name)] = reinterpret_cast<const char*>(value);
55         xmlFree(value);
56     }
57 }
58 
ParseSubItem(const xmlNode & parentNode,Item & item)59 void ConfigReader::ParseSubItem(const xmlNode& parentNode, Item& item)
60 {
61     auto currNodePtr = parentNode.xmlChildrenNode;
62     xmlChar *value;
63     for (; currNodePtr; currNodePtr = currNodePtr->next) {
64         if (IsInvalidNode(*currNodePtr)) {
65             RESSCHED_LOGW("ConfigReader::ParseSubItem skip invalid node!");
66             continue;
67         }
68         SubItem subItem;
69         ParseProperties(*currNodePtr, subItem.properties);
70         subItem.name = reinterpret_cast<const char*>(currNodePtr->name);
71         value = xmlNodeGetContent(currNodePtr);
72         if (value) {
73             string itemValue(reinterpret_cast<const char*>(value));
74             subItem.value = std::move(itemValue);
75             xmlFree(value);
76         }
77         item.subItemList.emplace_back(subItem);
78     }
79 }
80 
ParseItem(const xmlNode & parentNode,PluginConfig & pluginConfig)81 void ConfigReader::ParseItem(const xmlNode& parentNode, PluginConfig& pluginConfig)
82 {
83     auto currNodePtr = parentNode.xmlChildrenNode;
84     for (; currNodePtr; currNodePtr = currNodePtr->next) {
85         if (IsInvalidNode(*currNodePtr) ||
86             xmlStrcmp(currNodePtr->name, reinterpret_cast<const xmlChar*>(XML_TAG_ITEM)) != 0) {
87             continue;
88         }
89         Item item;
90         ParseProperties(*currNodePtr, item.itemProperties);
91         ParseSubItem(*currNodePtr, item);
92         pluginConfig.itemList.emplace_back(item);
93     }
94 }
95 
ParseConfig(const xmlNode & parentNode,PluginConfigMap & pluginConfigMap)96 void ConfigReader::ParseConfig(const xmlNode& parentNode, PluginConfigMap& pluginConfigMap)
97 {
98     auto currNodePtr = parentNode.xmlChildrenNode;
99     for (; currNodePtr; currNodePtr = currNodePtr->next) {
100         if (IsInvalidNode(*currNodePtr) ||
101             xmlStrcmp(currNodePtr->name, reinterpret_cast<const xmlChar*>(XML_TAG_CONFIG)) != 0) {
102             continue;
103         }
104         auto propName = xmlGetProp(currNodePtr, reinterpret_cast<const xmlChar*>(XML_ATTR_NAME));
105         if (!propName) {
106             RESSCHED_LOGW("ConfigReader::ParseConfig propName null!");
107             continue;
108         }
109 
110         string configName(reinterpret_cast<char*>(propName));
111         xmlFree(propName);
112         auto& pluginConfig = pluginConfigMap[configName];
113         ParseItem(*currNodePtr, pluginConfig);
114     }
115 }
116 
ParsePluginConfig(const xmlNode & currNode,map<string,PluginConfigMap> & pluginConfigs)117 bool ConfigReader::ParsePluginConfig(const xmlNode& currNode, map<string, PluginConfigMap>& pluginConfigs)
118 {
119     auto propName = xmlGetProp(&currNode, reinterpret_cast<const xmlChar*>(XML_ATTR_NAME));
120     if (!propName) {
121         RESSCHED_LOGW("ConfigReader::ParsePluginConfig propName null!");
122         return false;
123     }
124     string pluginName(reinterpret_cast<char*>(propName));
125     xmlFree(propName);
126     ParseConfig(currNode, pluginConfigs[pluginName]);
127     return true;
128 }
129 
LoadFromCustConfigFile(const string & configFile)130 bool ConfigReader::LoadFromCustConfigFile(const string& configFile)
131 {
132     // skip the empty string, else you will get empty node
133     xmlDocPtr xmlDocPtr = xmlReadFile(configFile.c_str(), nullptr, XML_PARSE_NOBLANKS);
134     if (!xmlDocPtr) {
135         RESSCHED_LOGE("ConfigReader::LoadFromCustConfigFile xmlReadFile error!");
136         return false;
137     }
138     xmlNodePtr rootNodePtr = xmlDocGetRootElement(xmlDocPtr);
139     if (!rootNodePtr || !rootNodePtr->name ||
140         xmlStrcmp(rootNodePtr->name, reinterpret_cast<const xmlChar*>(XML_TAG_RES_SCHED)) != 0) {
141         RESSCHED_LOGE("ConfigReader::LoadFromCustConfigFile root element tag wrong!");
142         xmlFreeDoc(xmlDocPtr);
143         return false;
144     }
145     map<string, PluginConfigMap> allPluginConfigs;
146     xmlNodePtr currNodePtr = rootNodePtr->xmlChildrenNode;
147     for (; currNodePtr; currNodePtr = currNodePtr->next) {
148         if (IsInvalidNode(*currNodePtr)) {
149             continue;
150         }
151         bool ret = false;
152         if (xmlStrcmp(currNodePtr->name, reinterpret_cast<const xmlChar*>(XML_TAG_PLUGIN)) == 0) {
153             ret = ParsePluginConfig(*currNodePtr, allPluginConfigs);
154         }
155         if (!ret) {
156             RESSCHED_LOGW("ConfigReader::LoadFromCustConfigFile plugin (%{public}s) config wrong!", currNodePtr->name);
157             xmlFreeDoc(xmlDocPtr);
158             return false;
159         }
160     }
161     xmlFreeDoc(xmlDocPtr);
162     lock_guard<mutex> autoLock(configMutex_);
163     allPluginConfigs_ = std::move(allPluginConfigs);
164     return true;
165 }
166 
GetConfig(const std::string & pluginName,const std::string & configName)167 PluginConfig ConfigReader::GetConfig(const std::string& pluginName, const std::string& configName)
168 {
169     lock_guard<mutex> autoLock(configMutex_);
170     PluginConfig config;
171     auto itMap = allPluginConfigs_.find(pluginName);
172     if (itMap == allPluginConfigs_.end()) {
173         RESSCHED_LOGE("ConfigReader::GetConfig no pluginName:%{public}s config!", pluginName.c_str());
174         return config;
175     }
176     PluginConfigMap configMap = allPluginConfigs_[pluginName];
177     auto itConfig = configMap.find(configName);
178     if (itConfig == configMap.end()) {
179         RESSCHED_LOGE("ConfigReader::GetConfig pluginName:%{public}s config:%{public}s null!",
180             pluginName.c_str(), configName.c_str());
181         return config;
182     }
183     return configMap[configName];
184 }
185 } // namespace ResourceSchedule
186 } // namespace OHOS