1 /*
2  * Copyright (C) 2023-2023 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 "xml_parser.h"
17 #include "wifi_logger.h"
18 #include <vector>
19 
20 namespace OHOS {
21 namespace Wifi {
22 DEFINE_WIFILOG_LABEL("XmlParser");
23 
~XmlParser()24 XmlParser::~XmlParser()
25 {
26     Destroy();
27 }
28 
Destroy()29 void XmlParser::Destroy()
30 {
31     if (mDoc_ != nullptr) {
32         xmlFreeDoc(mDoc_);
33         xmlCleanupParser();
34         mDoc_ = nullptr;
35     }
36 }
37 
LoadConfiguration(const char * xmlPath)38 bool XmlParser::LoadConfiguration(const char *xmlPath)
39 {
40     mDoc_ = xmlReadFile(xmlPath, nullptr, XML_PARSE_NOBLANKS);
41     if (mDoc_ == nullptr) {
42         WIFI_LOGE("LoadConfiguration fail");
43         return false;
44     }
45     return true;
46 }
47 
LoadConfigurationMemory(const char * xml)48 bool XmlParser::LoadConfigurationMemory(const char *xml)
49 {
50     if (xml == nullptr) {
51         WIFI_LOGE("LoadConfigurationMemory xml is nullptr");
52         return false;
53     }
54     mDoc_ = xmlReadMemory(xml, strlen(xml), nullptr, nullptr, 0);
55     if (mDoc_ == nullptr) {
56         WIFI_LOGE("LoadConfigurationMemory fail");
57         return false;
58     }
59     return true;
60 }
61 
Parse()62 bool XmlParser::Parse()
63 {
64     xmlNodePtr root = xmlDocGetRootElement(mDoc_);
65     if (root == nullptr) {
66         WIFI_LOGE("Parse root null");
67         return false;
68     }
69     return ParseInternal(root);
70 }
71 
GetNameValue(xmlNodePtr node)72 std::string XmlParser::GetNameValue(xmlNodePtr node)
73 {
74     if (node == nullptr || GetNodeValue(node).empty()) {
75         return "";
76     }
77     xmlChar *value = xmlGetProp(node, BAD_CAST"name");
78     if (value != nullptr) {
79         std::string result = std::string(reinterpret_cast<char *>(value));
80         xmlFree(value);
81         return result;
82     } else {
83         return "";
84     }
85 }
86 
GetNodeValue(xmlNodePtr node)87 std::string XmlParser::GetNodeValue(xmlNodePtr node)
88 {
89     if (node == nullptr) {
90         return "";
91     }
92     std::string nodeValue = std::string(reinterpret_cast<const char *>(node->name));
93     if (nodeValue.empty() || nodeValue == "null") {
94         return "";
95     }
96     return nodeValue;
97 }
98 
GetStringValue(xmlNodePtr node)99 std::string XmlParser::GetStringValue(xmlNodePtr node)
100 {
101     if (node == nullptr) {
102         return "";
103     }
104     xmlChar *value = xmlNodeGetContent(node);
105     std::string result = std::string(reinterpret_cast<char *>(value));
106     xmlFree(value);
107     return result;
108 }
109 
GetStringArrValue(xmlNodePtr innode)110 std::vector<std::string> XmlParser::GetStringArrValue(xmlNodePtr innode)
111 {
112     std::vector<std::string> stringArr{};
113     if (innode == nullptr) {
114         return stringArr;
115     }
116     xmlChar* numChar = xmlGetProp(innode, BAD_CAST"num");
117     int num = std::stoi(std::string(reinterpret_cast<char *>(numChar)));
118     xmlFree(numChar);
119     if (num == 0) {
120         return stringArr;
121     }
122     for (xmlNodePtr node = innode->children; node != nullptr; node = node->next) {
123         if (xmlStrcmp(node->name, BAD_CAST"item") == 0) {
124             xmlChar* value = xmlGetProp(node, BAD_CAST"value");
125             stringArr.push_back(std::string(reinterpret_cast<char *>(value)));
126             xmlFree(value);
127         }
128     }
129     return stringArr;
130 }
131 
GetByteArrValue(xmlNodePtr node)132 std::vector<unsigned char> XmlParser::GetByteArrValue(xmlNodePtr node)
133 {
134     std::vector<unsigned char> byteArr{};
135     if (node == nullptr) {
136         return byteArr;
137     }
138     xmlChar* numChar = xmlGetProp(node, BAD_CAST"num");
139     int num = std::stoi(std::string(reinterpret_cast<char *>(numChar)));
140     xmlChar *value = xmlNodeGetContent(node);
141     std::string valueStr = std::string(reinterpret_cast<char *>(value));
142     xmlFree(numChar);
143     xmlFree(value);
144     if (valueStr.length() != 2 * static_cast<size_t>(num)) { // byte length check
145         return byteArr;
146     }
147     for (size_t i = 0; i < valueStr.length(); i += 2) { // trans string to byte
148         std::string byteString = valueStr.substr(i, 2);
149         unsigned char byte = static_cast<unsigned char>(std::stoi(byteString, nullptr, 16)); // hex
150         byteArr.push_back(byte);
151     }
152     return byteArr;
153 }
154 
GetStringMapValue(xmlNodePtr innode)155 std::map<std::string, std::string> XmlParser::GetStringMapValue(xmlNodePtr innode)
156 {
157     std::map<std::string, std::string> strMap{};
158     if (innode == nullptr) {
159         return strMap;
160     }
161     for (xmlNodePtr node = innode->children; node != nullptr; node = node->next) {
162         std::string name;
163         std::string value;
164         if (xmlStrcmp(node->name, BAD_CAST"string") == 0) {
165             xmlChar* xname = xmlGetProp(node, BAD_CAST"name");
166             xmlChar* xvalue = xmlNodeGetContent(node);
167             name = std::string(reinterpret_cast<char *>(xname));
168             value = std::string(reinterpret_cast<char *>(xvalue));
169             strMap[name] = value;
170             xmlFree(xname);
171             xmlFree(xvalue);
172         }
173     }
174     return strMap;
175 }
176 
IsDocValid(xmlNodePtr node)177 bool XmlParser::IsDocValid(xmlNodePtr node)
178 {
179     if (node == nullptr) {
180         return false;
181     }
182     return (xmlStrcmp(node->name, BAD_CAST(XML_TAG_DOCUMENT_HEADER))  == 0);
183 }
184 }
185 }