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