• 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 "i_resource_compiler.h"
17 #include <algorithm>
18 #include <iostream>
19 #include "file_entry.h"
20 #include "id_worker.h"
21 #include "resource_util.h"
22 #include "restool_errors.h"
23 
24 namespace OHOS {
25 namespace Global {
26 namespace Restool {
27 using namespace std;
IResourceCompiler(ResType type,const string & output)28 IResourceCompiler::IResourceCompiler(ResType type, const string &output)
29     :type_(type), output_(output)
30 {
31 }
32 
~IResourceCompiler()33 IResourceCompiler::~IResourceCompiler()
34 {
35     nameInfos_.clear();
36     resourceInfos_.clear();
37 }
38 
Compile(const vector<DirectoryInfo> & directoryInfos)39 uint32_t IResourceCompiler::Compile(const vector<DirectoryInfo> &directoryInfos)
40 {
41     vector<FileInfo> fileInfos;
42     map<string, vector<FileInfo>> setsByDirectory;
43     for (const auto &directoryInfo : directoryInfos) {
44         string outputFolder = GetOutputFolder(directoryInfo);
45         FileEntry f(directoryInfo.dirPath);
46         if (!f.Init()) {
47             return RESTOOL_ERROR;
48         }
49         for (const auto &it : f.GetChilds()) {
50             if (ResourceUtil::IsIgnoreFile(it->GetFilePath().GetFilename(), it->IsFile())) {
51                 continue;
52             }
53 
54             if (!it->IsFile()) {
55                 cerr << "Error: '" << it->GetFilePath().GetPath() << "' must be a file." << endl;
56                 return RESTOOL_ERROR;
57             }
58 
59             FileInfo fileInfo = { directoryInfo, it->GetFilePath().GetPath(), it->GetFilePath().GetFilename() };
60             fileInfos.push_back(fileInfo);
61             setsByDirectory[outputFolder].push_back(fileInfo);
62         }
63     }
64 
65     sort(fileInfos.begin(), fileInfos.end(), [](const auto &a, const auto &b) {
66         return a.filePath < b.filePath;
67     });
68     for (const auto &fileInfo : fileInfos) {
69         if (CompileSingleFile(fileInfo) != RESTOOL_SUCCESS) {
70             return RESTOOL_ERROR;
71         }
72     }
73     return PostCommit();
74 }
75 
GetResult() const76 const map<int64_t, vector<ResourceItem>> &IResourceCompiler::GetResult() const
77 {
78     return resourceInfos_;
79 }
80 
Compile(const FileInfo & fileInfo)81 uint32_t IResourceCompiler::Compile(const FileInfo &fileInfo)
82 {
83     if (CompileSingleFile(fileInfo) != RESTOOL_SUCCESS) {
84         return RESTOOL_ERROR;
85     }
86     return PostCommit();
87 }
88 
CompileForAppend(const FileInfo & fileInfo)89 uint32_t IResourceCompiler::CompileForAppend(const FileInfo &fileInfo)
90 {
91     return CompileSingleFile(fileInfo);
92 }
93 
GetResourceItems() const94 const map<pair<ResType, string>, vector<ResourceItem>> &IResourceCompiler::GetResourceItems() const
95 {
96     return nameInfos_;
97 }
98 
SetModuleName(const string & moduleName)99 void IResourceCompiler::SetModuleName(const string &moduleName)
100 {
101     moduleName_ = moduleName;
102 }
103 
CompileSingleFile(const FileInfo & fileInfo)104 uint32_t IResourceCompiler::CompileSingleFile(const FileInfo &fileInfo)
105 {
106     return RESTOOL_SUCCESS;
107 }
108 
PostCommit()109 uint32_t IResourceCompiler::PostCommit()
110 {
111     IdWorker &idWorker = IdWorker::GetInstance();
112     for (const auto &nameInfo : nameInfos_) {
113         int64_t id = idWorker.GenerateId(nameInfo.first.first, nameInfo.first.second);
114         if (id < 0) {
115             cerr << "Error: restype='" << ResourceUtil::ResTypeToString(nameInfo.first.first) << "' name='";
116             cerr << nameInfo.first.second << "' id not be defined." << endl;
117             return RESTOOL_ERROR;
118         }
119         resourceInfos_.emplace(id, nameInfo.second);
120     }
121     return RESTOOL_SUCCESS;
122 }
123 
MergeResourceItem(const ResourceItem & resourceItem)124 bool IResourceCompiler::MergeResourceItem(const ResourceItem &resourceItem)
125 {
126     string idName = ResourceUtil::GetIdName(resourceItem.GetName(), resourceItem.GetResType());
127     if (!ResourceUtil::IsValidName(idName)) {
128         cerr << "Error: invalid idName '" << idName << "'."<< NEW_LINE_PATH <<  resourceItem.GetFilePath() << endl;
129         cerr << SOLUTIONS << endl;
130         cerr << SOLUTIONS_ARROW << "Modify the name '" << idName << "' to match [a-zA-Z0-9_]." << endl;
131         return false;
132     }
133     auto item = nameInfos_.find(make_pair(resourceItem.GetResType(), idName));
134     if (item == nameInfos_.end()) {
135         nameInfos_[make_pair(resourceItem.GetResType(), idName)].push_back(resourceItem);
136         return true;
137     }
138 
139     auto ret = find_if(item->second.begin(), item->second.end(), [resourceItem](auto &iter) {
140         return resourceItem.GetLimitKey() == iter.GetLimitKey();
141     });
142     if (ret != item->second.end()) {
143         cerr << "Error: resource '" << idName << "' first declared." << NEW_LINE_PATH << ret->GetFilePath() << endl;
144         cerr << "but declare again." << NEW_LINE_PATH << resourceItem.GetFilePath() << endl;
145         return false;
146     }
147 
148     nameInfos_[make_pair(resourceItem.GetResType(), idName)].push_back(resourceItem);
149     return true;
150 }
151 
GetOutputFolder(const DirectoryInfo & directoryInfo) const152 string IResourceCompiler::GetOutputFolder(const DirectoryInfo &directoryInfo) const
153 {
154     string outputFolder = FileEntry::FilePath(output_).Append(RESOURCES_DIR)
155         .Append(directoryInfo.limitKey).Append(directoryInfo.fileCluster).GetPath();
156     return outputFolder;
157 }
158 }
159 }
160 }
161