• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2024 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 <dualfwk_conf_parser.h>
17 
18 #include <charconv>
19 #include <functional>
20 #include <string>
21 #include <vector>
22 #include <unordered_map>
23 
24 #include <libxml/tree.h>
25 #include <libxml/parser.h>
26 
27 #include "ringtone_errno.h"
28 #include "ringtone_log.h"
29 #include "ringtone_type.h"
30 #include "ringtone_utils.h"
31 
32 namespace OHOS {
33 namespace Media {
DualFwkConfParser(const std::string & path)34 DualFwkConfParser::DualFwkConfParser(const std::string &path)
35     : version_(0), path_(path)
36 {
37 }
38 
StringConverter(const std::string & str,int & result)39 bool DualFwkConfParser::StringConverter(const std::string &str, int &result)
40 {
41     auto [ptr, ec] = std::from_chars(str.data(), str.data() + str.size(), result);
42     return ec == std::errc{} && ptr == str.data() + str.size();
43 }
44 
Parse()45 int32_t DualFwkConfParser::Parse()
46 {
47     std::unique_ptr<xmlDoc, decltype(&xmlFreeDoc)> docPtr(
48         xmlReadFile(path_.c_str(), nullptr, XML_PARSE_NOBLANKS), xmlFreeDoc);
49     if (docPtr == nullptr) {
50         RINGTONE_ERR_LOG("failed to read xml file");
51         return E_ERR;
52     }
53 
54     auto rootNode = xmlDocGetRootElement(docPtr.get());
55     if (rootNode == nullptr) {
56         RINGTONE_ERR_LOG("failed to read root node");
57         return E_ERR;
58     }
59 
60     if (!xmlStrcmp(rootNode->name, BAD_CAST"settings")) {
61         xmlChar* xmlVersion = xmlGetProp(rootNode, BAD_CAST"version");
62         if (xmlVersion == nullptr) {
63             RINGTONE_ERR_LOG("xml version is null");
64             return E_ERR;
65         }
66         try {
67             version_ = std::stoi((const char *)xmlVersion);
68             RINGTONE_INFO_LOG("xml verison=%{public}d", version_);
69         } catch (const std::invalid_argument& e) {
70             RINGTONE_INFO_LOG("invalid argument: %{public}s", e.what());
71         } catch (const std::out_of_range& e) {
72             RINGTONE_INFO_LOG("out of range: %{public}s", e.what());
73         }
74 
75         if (xmlVersion != nullptr) {
76             int32_t value = 0;
77             if (RingtoneUtils::IsNumber((const char *)xmlVersion) &&
78                 StringConverter((const char *)xmlVersion, value)) {
79                 version_ = value;
80                 RINGTONE_INFO_LOG("xml verison=%{public}d", version_);
81                 xmlFree(xmlVersion);
82             }
83         } else {
84             RINGTONE_INFO_LOG("xml version is null");
85         }
86     } else {
87         RINGTONE_ERR_LOG("root node name is not matched");
88         return E_ERR;
89     }
90 
91     for (auto node = rootNode->children; node != nullptr; node = node->next) {
92         if (!xmlStrcmp(node->name, BAD_CAST"setting")) {
93             ParseConf(node);
94         } else {
95             RINGTONE_INFO_LOG("bad node name: %{public}s", node->name);
96         }
97     }
98 
99     return E_SUCCESS;
100 }
101 
ParseConf(xmlNodePtr node)102 int32_t DualFwkConfParser::ParseConf(xmlNodePtr node)
103 {
104     auto conf = std::make_unique<DualFwkConfRow>();
105     xmlChar* xmlAttrVal = xmlGetProp(node, BAD_CAST"id");
106     if (xmlAttrVal) {
107         try {
108             int num = std::stoi((const char *)xmlAttrVal);
109             conf->id = num;
110         } catch (const std::invalid_argument& e) {
111             conf->id = -1;
112             RINGTONE_INFO_LOG("invalid argument: %{public}s", e.what());
113         } catch (const std::out_of_range& e) {
114             conf->id = -1;
115             RINGTONE_INFO_LOG("out of range: %{public}s", e.what());
116         }
117         xmlFree(xmlAttrVal);
118     }
119     auto strName = reinterpret_cast<char*>(xmlGetProp(node, BAD_CAST"name"));
120     if (strName != nullptr) {
121         conf->name = std::string(strName);
122         xmlFree(strName);
123     }
124 
125     auto strVal = reinterpret_cast<char*>(xmlGetProp(node, BAD_CAST"value"));
126     if (strVal != nullptr) {
127         conf->value = std::string(strVal);
128         xmlFree(strVal);
129     }
130 
131     auto strPackage = reinterpret_cast<char*>(xmlGetProp(node, BAD_CAST"package"));
132     if (strPackage != nullptr) {
133         conf->package = std::string(strPackage);
134         xmlFree(strPackage);
135     }
136 
137     auto strDefaultVal = reinterpret_cast<char*>(xmlGetProp(node, BAD_CAST"defaultValue"));
138     if (strDefaultVal != nullptr) {
139         conf->defaultValue = std::string(strDefaultVal);
140         xmlFree(strDefaultVal);
141     }
142 
143     auto strDefaultSysSet = reinterpret_cast<char*>(xmlGetProp(node, BAD_CAST"defaultSysSet"));
144     if (strDefaultSysSet != nullptr) {
145         conf->defaultSysSet = std::string(strDefaultSysSet);
146         xmlFree(strDefaultSysSet);
147     }
148 
149     auto strPreserve = reinterpret_cast<char*>(xmlGetProp(node, BAD_CAST"preserve_in_restore"));
150     if (strPreserve != nullptr) {
151         conf->preserveInRestore = (std::string(strPreserve) == "true" ? true : false);
152         xmlFree(strPreserve);
153     }
154 
155     dualFwkConfs_.push_back(std::move(conf));
156 
157     return E_SUCCESS;
158 }
159 
ConfTraval(std::function<void (std::unique_ptr<DualFwkConfRow> &)> func)160 void DualFwkConfParser::ConfTraval(std::function<void (std::unique_ptr<DualFwkConfRow> &)> func)
161 {
162     RINGTONE_INFO_LOG("dualfwk confs num: %{public}zu", dualFwkConfs_.size());
163     for (size_t i = 0; i < dualFwkConfs_.size(); i++) {
164         func(dualFwkConfs_[i]);
165     }
166 }
167 } // namespace Media
168 } // namespace OHOS
169