• 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 
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     auto strVal = reinterpret_cast<char*>(xmlGetProp(node, BAD_CAST"name"));
118     if (strVal != nullptr) {
119         conf->name = std::string(strVal);
120     }
121 
122     strVal = reinterpret_cast<char*>(xmlGetProp(node, BAD_CAST"value"));
123     if (strVal != nullptr) {
124         conf->value = std::string(strVal);
125     }
126 
127     strVal = reinterpret_cast<char*>(xmlGetProp(node, BAD_CAST"package"));
128     if (strVal != nullptr) {
129         conf->package = std::string(strVal);
130     }
131 
132     strVal = reinterpret_cast<char*>(xmlGetProp(node, BAD_CAST"defaultValue"));
133     if (strVal != nullptr) {
134         conf->defaultValue = std::string(strVal);
135     }
136 
137     strVal = reinterpret_cast<char*>(xmlGetProp(node, BAD_CAST"defaultSysSet"));
138     if (strVal != nullptr) {
139         conf->defaultSysSet = std::string(strVal);
140     }
141 
142     strVal = reinterpret_cast<char*>(xmlGetProp(node, BAD_CAST"preserve_in_restore"));
143     if (strVal != nullptr) {
144         conf->preserveInRestore = (std::string(strVal) == "true" ? true : false);
145     }
146 
147     dualFwkConfs_.push_back(std::move(conf));
148 
149     return E_SUCCESS;
150 }
151 
ConfTraval(std::function<void (std::unique_ptr<DualFwkConfRow> &)> func)152 void DualFwkConfParser::ConfTraval(std::function<void (std::unique_ptr<DualFwkConfRow> &)> func)
153 {
154     RINGTONE_INFO_LOG("dualfwk confs num: %{public}zu", dualFwkConfs_.size());
155     for (size_t i = 0; i < dualFwkConfs_.size(); i++) {
156         func(dualFwkConfs_[i]);
157     }
158 }
159 } // namespace Media
160 } // namespace OHOS
161