• 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,bool isOverlap)28 IResourceCompiler::IResourceCompiler(ResType type, const string &output, bool isOverlap)
29     :type_(type), output_(output), isOverlap_(isOverlap)
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                 PrintError(GetError(ERR_CODE_INVALID_RESOURCE_PATH)
56                     .FormatCause(it->GetFilePath().GetPath().c_str(), "not a file"));
57                 return RESTOOL_ERROR;
58             }
59 
60             FileInfo fileInfo = { directoryInfo, it->GetFilePath().GetPath(), it->GetFilePath().GetFilename() };
61             fileInfos.push_back(fileInfo);
62             setsByDirectory[outputFolder].push_back(fileInfo);
63         }
64     }
65 
66     sort(fileInfos.begin(), fileInfos.end(), [](const auto &a, const auto &b) {
67         return a.filePath < b.filePath;
68     });
69     if (CompileFiles(fileInfos) != RESTOOL_SUCCESS) {
70         return RESTOOL_ERROR;
71     }
72     return PostCommit();
73 }
74 
CompileFiles(const std::vector<FileInfo> & fileInfos)75 uint32_t IResourceCompiler::CompileFiles(const std::vector<FileInfo> &fileInfos)
76 {
77     for (const auto &fileInfo : fileInfos) {
78         if (CompileSingleFile(fileInfo) != RESTOOL_SUCCESS) {
79             return RESTOOL_ERROR;
80         }
81     }
82     return RESTOOL_SUCCESS;
83 }
84 
GetResult() const85 const map<int64_t, vector<ResourceItem>> &IResourceCompiler::GetResult() const
86 {
87     return resourceInfos_;
88 }
89 
Compile(const FileInfo & fileInfo)90 uint32_t IResourceCompiler::Compile(const FileInfo &fileInfo)
91 {
92     if (CompileSingleFile(fileInfo) != RESTOOL_SUCCESS) {
93         return RESTOOL_ERROR;
94     }
95     return PostCommit();
96 }
97 
CompileForAppend(const FileInfo & fileInfo)98 uint32_t IResourceCompiler::CompileForAppend(const FileInfo &fileInfo)
99 {
100     return CompileSingleFile(fileInfo);
101 }
102 
GetResourceItems() const103 const map<pair<ResType, string>, vector<ResourceItem>> &IResourceCompiler::GetResourceItems() const
104 {
105     return nameInfos_;
106 }
107 
SetModuleName(const string & moduleName)108 void IResourceCompiler::SetModuleName(const string &moduleName)
109 {
110     moduleName_ = moduleName;
111 }
112 
CompileSingleFile(const FileInfo & fileInfo)113 uint32_t IResourceCompiler::CompileSingleFile(const FileInfo &fileInfo)
114 {
115     return RESTOOL_SUCCESS;
116 }
117 
PostCommit()118 uint32_t IResourceCompiler::PostCommit()
119 {
120     IdWorker &idWorker = IdWorker::GetInstance();
121     for (const auto &nameInfo : nameInfos_) {
122         int64_t id = idWorker.GenerateId(nameInfo.first.first, nameInfo.first.second);
123         if (id < 0) {
124             PrintError(GetError(ERR_CODE_RESOURCE_ID_NOT_DEFINED)
125                            .FormatCause(nameInfo.first.second.c_str(),
126                                         ResourceUtil::ResTypeToString(nameInfo.first.first).c_str()));
127             return RESTOOL_ERROR;
128         }
129         resourceInfos_.emplace(id, nameInfo.second);
130     }
131     return RESTOOL_SUCCESS;
132 }
133 
MergeResourceItem(const ResourceItem & resourceItem)134 bool IResourceCompiler::MergeResourceItem(const ResourceItem &resourceItem)
135 {
136     string idName = ResourceUtil::GetIdName(resourceItem.GetName(), resourceItem.GetResType());
137     if (!ResourceUtil::IsValidName(idName)) {
138         PrintError(GetError(ERR_CODE_INVALID_RESOURCE_NAME).FormatCause(idName.c_str())
139             .SetPosition(resourceItem.GetFilePath()));
140         return false;
141     }
142     auto item = nameInfos_.find(make_pair(resourceItem.GetResType(), idName));
143     if (item == nameInfos_.end()) {
144         nameInfos_[make_pair(resourceItem.GetResType(), idName)].push_back(resourceItem);
145         return true;
146     }
147 
148     auto ret = find_if(item->second.begin(), item->second.end(), [resourceItem](auto &iter) {
149         return resourceItem.GetLimitKey() == iter.GetLimitKey();
150     });
151     if (ret != item->second.end()) {
152         PrintError(GetError(ERR_CODE_RESOURCE_DUPLICATE)
153                        .FormatCause(idName.c_str(), ret->GetFilePath().c_str(), resourceItem.GetFilePath().c_str()));
154         return false;
155     }
156     nameInfos_[make_pair(resourceItem.GetResType(), idName)].push_back(resourceItem);
157     return true;
158 }
159 
GetOutputFolder(const DirectoryInfo & directoryInfo) const160 string IResourceCompiler::GetOutputFolder(const DirectoryInfo &directoryInfo) const
161 {
162     string outputFolder = FileEntry::FilePath(output_).Append(RESOURCES_DIR)
163         .Append(directoryInfo.limitKey).Append(directoryInfo.fileCluster).GetPath();
164     return outputFolder;
165 }
166 }
167 }
168 }
169