1 /*
2 * Copyright (c) 2021 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 "solid_xml_compiler.h"
17 #include<iostream>
18 #include<regex>
19 #include "resource_util.h"
20 #include "restool_errors.h"
21
22 namespace OHOS {
23 namespace Global {
24 namespace Restool {
25 using namespace std;
SolidXmlCompiler(ResType type,const string & output)26 SolidXmlCompiler::SolidXmlCompiler(ResType type, const string &output)
27 : GenericCompiler(type, output)
28 {
29 }
30
~SolidXmlCompiler()31 SolidXmlCompiler::~SolidXmlCompiler()
32 {
33 }
34
CompileSingleFile(const FileInfo & fileInfo)35 uint32_t SolidXmlCompiler::CompileSingleFile(const FileInfo &fileInfo)
36 {
37 if (!IsXmlFile(fileInfo)) {
38 cerr << "Error: '" << fileInfo.filePath << "' should be xml file." << endl;
39 return RESTOOL_ERROR;
40 }
41
42 if (HasConvertedToSolidXml(fileInfo)) {
43 return RESTOOL_SUCCESS;
44 }
45
46 if (!PostFile(fileInfo)) {
47 return RESTOOL_ERROR;
48 }
49
50 if (!ParseXml(fileInfo)) {
51 return RESTOOL_ERROR;
52 }
53 return RESTOOL_SUCCESS;
54 }
55
ParseXml(const FileInfo & fileInfo)56 bool SolidXmlCompiler::ParseXml(const FileInfo &fileInfo)
57 {
58 xmlKeepBlanksDefault(0);
59 xmlDocPtr doc = xmlParseFile(fileInfo.filePath.c_str());
60 if (doc == nullptr) {
61 return false;
62 }
63
64 vector<string> ids;
65 bool result = ParseNodeId(fileInfo, xmlDocGetRootElement(doc), ids);
66 xmlFreeDoc(doc);
67 if (!result) {
68 return false;
69 }
70
71 for (const auto &id : ids) {
72 ResourceItem resourceItem(id, fileInfo.keyParams, ResType::ID);
73 resourceItem.SetFilePath(fileInfo.filePath);
74 resourceItem.SetLimitKey(fileInfo.limitKey);
75 if (!MergeResourceItem(resourceItem)) {
76 return false;
77 }
78 }
79 return true;
80 }
81
ParseNodeId(const FileInfo & fileInfo,const xmlNodePtr & node,vector<string> & ids)82 bool SolidXmlCompiler::ParseNodeId(const FileInfo &fileInfo, const xmlNodePtr &node, vector<string> &ids)
83 {
84 if (node == nullptr) {
85 return true;
86 }
87
88 if (node->type == XML_COMMENT_NODE) {
89 return ParseNodeId(fileInfo, node->next, ids);
90 }
91
92 string idValue;
93 xmlChar * xmlValue = xmlGetProp(node, BAD_CAST "id");
94 if (xmlValue != nullptr) {
95 idValue = string(reinterpret_cast<const char *>(xmlValue));
96 xmlFree(xmlValue);
97 }
98
99 regex ref("^\\$\\+id:");
100 smatch result;
101 if (regex_search(idValue, result, ref)) {
102 string name = idValue.substr(result[0].str().size());
103 if (find(ids.begin(), ids.end(), name) != ids.end()) {
104 cerr << "Error: '" << idValue << "' duplicated in " << fileInfo.filePath << endl;
105 return false;
106 }
107 ids.push_back(name);
108 }
109
110 if (!ParseNodeId(fileInfo, node->children, ids)) {
111 return false;
112 }
113
114 if (!ParseNodeId(fileInfo, node->next, ids)) {
115 return false;
116 }
117 return true;
118 }
119 }
120 }
121 }
122