• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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