• 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("%{public}s, name null!", __func__);
47             continue;
48         }
49         value = xmlGetProp(&currNode, name);
50         if (!value) {
51             RESSCHED_LOGW("%{public}s, name(%{public}s) value null!", __func__, 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("%{public}s, skip invalid node!", __func__);
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("%{public}s, propName null!", __func__);
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("%{public}s, propName null!", __func__);
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,
134         XML_PARSE_NOBLANKS | XML_PARSE_NOERROR | XML_PARSE_NOWARNING);
135     if (!xmlDocPtr) {
136         RESSCHED_LOGE("%{public}s, xmlReadFile error!", __func__);
137         return false;
138     }
139     xmlNodePtr rootNodePtr = xmlDocGetRootElement(xmlDocPtr);
140     if (!rootNodePtr || !rootNodePtr->name ||
141         xmlStrcmp(rootNodePtr->name, reinterpret_cast<const xmlChar*>(XML_TAG_RES_SCHED)) != 0) {
142         RESSCHED_LOGE("%{public}s, root element tag wrong!", __func__);
143         xmlFreeDoc(xmlDocPtr);
144         return false;
145     }
146     map<string, PluginConfigMap> allPluginConfigs;
147     xmlNodePtr currNodePtr = rootNodePtr->xmlChildrenNode;
148     for (; currNodePtr; currNodePtr = currNodePtr->next) {
149         if (IsInvalidNode(*currNodePtr)) {
150             continue;
151         }
152         bool ret = false;
153         if (xmlStrcmp(currNodePtr->name, reinterpret_cast<const xmlChar*>(XML_TAG_PLUGIN)) == 0) {
154             ret = ParsePluginConfig(*currNodePtr, allPluginConfigs);
155         }
156         if (!ret) {
157             RESSCHED_LOGW("%{public}s, plugin (%{public}s) config wrong!", __func__, currNodePtr->name);
158             xmlFreeDoc(xmlDocPtr);
159             return false;
160         }
161     }
162     xmlFreeDoc(xmlDocPtr);
163     lock_guard<mutex> autoLock(configMutex_);
164     allPluginConfigs_ = std::move(allPluginConfigs);
165     return true;
166 }
167 
GetConfig(const std::string & pluginName,const std::string & configName)168 PluginConfig ConfigReader::GetConfig(const std::string& pluginName, const std::string& configName)
169 {
170     lock_guard<mutex> autoLock(configMutex_);
171     PluginConfig config;
172     auto itMap = allPluginConfigs_.find(pluginName);
173     if (itMap == allPluginConfigs_.end()) {
174         RESSCHED_LOGE("%{public}s, no pluginName:%{public}s config!", __func__, pluginName.c_str());
175         return config;
176     }
177     PluginConfigMap configMap = allPluginConfigs_[pluginName];
178     auto itConfig = configMap.find(configName);
179     if (itConfig == configMap.end()) {
180         RESSCHED_LOGE("%{public}s, pluginName:%{public}s config:%{public}s null!", __func__,
181             pluginName.c_str(), configName.c_str());
182         return config;
183     }
184     return configMap[configName];
185 }
186 } // namespace ResourceSchedule
187 } // namespace OHOS
188