• 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 
16 #include "configuration_helper.h"
17 
18 #include <functional>
19 
20 #include <securec.h>
21 #include <unistd.h>
22 
23 #include "vpe_log.h"
24 
25 using namespace OHOS::Media::VideoProcessingEngine;
26 
27 namespace {
GetElementInfo(const xmlNode & parent,const std::string & tag,std::function<const std::string (const xmlNode &)> && getter)28 inline const std::string GetElementInfo(const xmlNode& parent, const std::string& tag,
29     std::function<const std::string(const xmlNode&)>&& getter)
30 {
31     const xmlNode* node = parent.children;
32     CHECK_AND_RETURN_RET_LOG(node != nullptr, "", "No children when finding <%{public}s>!", tag.c_str());
33     CHECK_AND_RETURN_RET_LOG(xmlStrcmp(node->name, reinterpret_cast<const xmlChar*>(tag.c_str())) == 0, "",
34         "Element <%{public}s> is not found!", tag.c_str());
35     return getter(*node);
36 }
37 
GetElement(const xmlNode & parent,const std::string & tag,std::function<bool (const xmlNode &)> && checker,const std::string & notFoundLog)38 inline const xmlNode* GetElement(const xmlNode& parent, const std::string& tag,
39     std::function<bool(const xmlNode&)>&& checker, const std::string& notFoundLog)
40 {
41     for (const xmlNode* node = parent.children; node != nullptr; node = node->next) {
42         if (xmlStrcmp(node->name, reinterpret_cast<const xmlChar*>(tag.c_str())) != 0) {
43             continue;
44         }
45         if (checker(*node)) {
46             return node;
47         }
48     }
49     VPE_LOGW("%{public}s is NOT found!", notFoundLog.c_str());
50     return nullptr;
51 }
52 }
53 
LoadConfigurationFromXml(const std::string & xmlFilePath)54 bool ConfigurationHelper::LoadConfigurationFromXml(const std::string& xmlFilePath)
55 {
56     if (access(xmlFilePath.c_str(), R_OK) != 0) [[unlikely]] {
57         VPE_LOGW("Invalid input: %{public}s is NOT exist!", xmlFilePath.c_str());
58         return false;
59     }
60 
61     xmlDocPtr doc = xmlParseFile(xmlFilePath.c_str());
62     if (doc == nullptr) [[unlikely]] {
63         VPE_LOGW("Failed to parse %{public}s!", xmlFilePath.c_str());
64         return false;
65     }
66 
67     xmlNode* root = xmlDocGetRootElement(doc);
68     if (root == nullptr) [[unlikely]] {
69         VPE_LOGW("Failed to parse %{public}s: there is no root element!", xmlFilePath.c_str());
70         xmlFreeDoc(doc);
71         return false;
72     }
73 
74     auto ret = ParseXml(*root);
75     if (!ret) {
76         VPE_LOGW("Failed to parse %{public}s: Content is invalid!", xmlFilePath.c_str());
77     }
78     xmlFreeDoc(doc);
79     return ret;
80 }
81 
ParseXml(const xmlNode & root)82 bool ConfigurationHelper::ParseXml([[maybe_unused]] const xmlNode& root)
83 {
84     return true;
85 }
86 
GetElement(const xmlNode & parent,const std::string & tag) const87 const xmlNode* ConfigurationHelper::GetElement(const xmlNode& parent, const std::string& tag) const
88 {
89     return ::GetElement(parent, tag, [](const xmlNode&) { return true; }, "<" + tag + ">");
90 }
91 
GetElementByName(const xmlNode & parent,const std::string & tag,const std::string & name) const92 const xmlNode* ConfigurationHelper::GetElementByName(const xmlNode& parent,
93     const std::string& tag, const std::string& name) const
94 {
95     return ::GetElement(parent, tag, [&tag, &name](const xmlNode& node) {
96         const xmlChar* nameText = xmlGetProp(&node, reinterpret_cast<const xmlChar*>("name"));
97         if (nameText == nullptr) {
98             VPE_LOGD("name of <%{public}s> is null!", tag.c_str());
99             return false;
100         }
101         return name.compare(reinterpret_cast<const char*>(nameText)) == 0;
102     }, "<" + tag + " name=\"" + name + "\">");
103 }
104 
GetElementName(const xmlNode & parent,const std::string & tag) const105 const std::string ConfigurationHelper::GetElementName(const xmlNode& parent, const std::string& tag) const
106 {
107     return GetElementInfo(parent, tag, [this](const xmlNode& node) { return GetElementName(node); });
108 }
109 
GetElementName(const xmlNode & myself) const110 const std::string ConfigurationHelper::GetElementName(const xmlNode& myself) const
111 {
112     const char* nameText = reinterpret_cast<char*>(xmlGetProp(&myself, reinterpret_cast<const xmlChar*>("name")));
113     CHECK_AND_RETURN_RET_LOG(nameText != nullptr, "", "name of <%{public}s> is null!", myself.name);
114     return std::string(nameText);
115 }
116 
GetElementText(const xmlNode & parent,const std::string & tag) const117 const std::string ConfigurationHelper::GetElementText(const xmlNode& parent, const std::string& tag) const
118 {
119     return GetElementInfo(parent, tag, [this](const xmlNode& node) { return GetElementText(node); });
120 }
121 
GetElementText(const xmlNode & myself) const122 const std::string ConfigurationHelper::GetElementText(const xmlNode& myself) const
123 {
124     const char* text = reinterpret_cast<char*>(xmlNodeGetContent(&myself));
125     CHECK_AND_RETURN_RET_LOG(text != nullptr, "", "Element <%{public}s> is empty!", myself.name);
126     return std::string(text);
127 }
128 
GetElementValue(const xmlNode & parent,const std::string & tag,uint32_t & value) const129 bool ConfigurationHelper::GetElementValue(const xmlNode& parent, const std::string& tag, uint32_t& value) const
130 {
131     value = 0;
132     const std::string& text = GetElementText(parent, tag);
133     if (text.empty()) {
134         return false;
135     }
136     return sscanf_s(text.c_str(), "%u", &value) == 1;
137 }
138 
GetElementValue(const xmlNode & parent,const std::string & tag,int & value) const139 bool ConfigurationHelper::GetElementValue(const xmlNode& parent, const std::string& tag, int& value) const
140 {
141     value = 0;
142     const std::string& text = GetElementText(parent, tag);
143     if (text.empty()) {
144         return false;
145     }
146     return sscanf_s(text.c_str(), "%d", &value) == 1;
147 }
148 
GetElementValue(const xmlNode & parent,const std::string & tag,uint64_t & value) const149 bool ConfigurationHelper::GetElementValue(const xmlNode& parent, const std::string& tag, uint64_t& value) const
150 {
151     value = 0;
152     const std::string& text = GetElementText(parent, tag);
153     if (text.empty()) {
154         return false;
155     }
156     return sscanf_s(text.c_str(), "%lu", &value) == 1;
157 }
158 
GetElementValue(const xmlNode & parent,const std::string & tag,bool & value) const159 bool ConfigurationHelper::GetElementValue(const xmlNode& parent, const std::string& tag, bool& value) const
160 {
161     const std::string& text = GetElementText(parent, tag);
162     if (text.empty()) {
163         value = false;
164         return false;
165     }
166     value = (text.compare("true") == 0);
167     return true;
168 }
169 
GetElementValue(const xmlNode & parent,const std::string & tag,float & value) const170 bool ConfigurationHelper::GetElementValue(const xmlNode& parent, const std::string& tag, float& value) const
171 {
172     value = 0;
173     const std::string& text = GetElementText(parent, tag);
174     if (text.empty()) {
175         return false;
176     }
177     return sscanf_s(text.c_str(), "%f", &value) == 1;
178 }
179 
GetElementValue(const xmlNode & parent,const std::string & tag,std::string & value) const180 bool ConfigurationHelper::GetElementValue(const xmlNode& parent, const std::string& tag, std::string& value) const
181 {
182     value = GetElementText(parent, tag);
183     return !value.empty();
184 }
185 
GetElementValue(const xmlNode & myself,std::string & value) const186 bool ConfigurationHelper::GetElementValue(const xmlNode& myself, std::string& value) const
187 {
188     value = GetElementText(myself);
189     return !value.empty();
190 }
191