13920e296Sopenharmony_ci/* 23920e296Sopenharmony_ci * Copyright (c) 2021 Huawei Device Co., Ltd. 33920e296Sopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License"); 43920e296Sopenharmony_ci * you may not use this file except in compliance with the License. 53920e296Sopenharmony_ci * You may obtain a copy of the License at 63920e296Sopenharmony_ci * 73920e296Sopenharmony_ci * http://www.apache.org/licenses/LICENSE-2.0 83920e296Sopenharmony_ci * 93920e296Sopenharmony_ci * Unless required by applicable law or agreed to in writing, software 103920e296Sopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS, 113920e296Sopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 123920e296Sopenharmony_ci * See the License for the specific language governing permissions and 133920e296Sopenharmony_ci * limitations under the License. 143920e296Sopenharmony_ci */ 153920e296Sopenharmony_ci 163920e296Sopenharmony_ci#include "i_resource_compiler.h" 173920e296Sopenharmony_ci#include <algorithm> 183920e296Sopenharmony_ci#include <iostream> 193920e296Sopenharmony_ci#include "file_entry.h" 203920e296Sopenharmony_ci#include "id_worker.h" 213920e296Sopenharmony_ci#include "resource_util.h" 223920e296Sopenharmony_ci#include "restool_errors.h" 233920e296Sopenharmony_ci 243920e296Sopenharmony_cinamespace OHOS { 253920e296Sopenharmony_cinamespace Global { 263920e296Sopenharmony_cinamespace Restool { 273920e296Sopenharmony_ciusing namespace std; 283920e296Sopenharmony_ciIResourceCompiler::IResourceCompiler(ResType type, const string &output) 293920e296Sopenharmony_ci :type_(type), output_(output) 303920e296Sopenharmony_ci{ 313920e296Sopenharmony_ci} 323920e296Sopenharmony_ci 333920e296Sopenharmony_ciIResourceCompiler::~IResourceCompiler() 343920e296Sopenharmony_ci{ 353920e296Sopenharmony_ci nameInfos_.clear(); 363920e296Sopenharmony_ci resourceInfos_.clear(); 373920e296Sopenharmony_ci} 383920e296Sopenharmony_ci 393920e296Sopenharmony_ciuint32_t IResourceCompiler::Compile(const vector<DirectoryInfo> &directoryInfos) 403920e296Sopenharmony_ci{ 413920e296Sopenharmony_ci vector<FileInfo> fileInfos; 423920e296Sopenharmony_ci map<string, vector<FileInfo>> setsByDirectory; 433920e296Sopenharmony_ci for (const auto &directoryInfo : directoryInfos) { 443920e296Sopenharmony_ci string outputFolder = GetOutputFolder(directoryInfo); 453920e296Sopenharmony_ci FileEntry f(directoryInfo.dirPath); 463920e296Sopenharmony_ci if (!f.Init()) { 473920e296Sopenharmony_ci return RESTOOL_ERROR; 483920e296Sopenharmony_ci } 493920e296Sopenharmony_ci for (const auto &it : f.GetChilds()) { 503920e296Sopenharmony_ci if (ResourceUtil::IsIgnoreFile(it->GetFilePath().GetFilename(), it->IsFile())) { 513920e296Sopenharmony_ci continue; 523920e296Sopenharmony_ci } 533920e296Sopenharmony_ci 543920e296Sopenharmony_ci if (!it->IsFile()) { 553920e296Sopenharmony_ci cerr << "Error: '" << it->GetFilePath().GetPath() << "' must be a file." << endl; 563920e296Sopenharmony_ci return RESTOOL_ERROR; 573920e296Sopenharmony_ci } 583920e296Sopenharmony_ci 593920e296Sopenharmony_ci FileInfo fileInfo = { directoryInfo, it->GetFilePath().GetPath(), it->GetFilePath().GetFilename() }; 603920e296Sopenharmony_ci fileInfos.push_back(fileInfo); 613920e296Sopenharmony_ci setsByDirectory[outputFolder].push_back(fileInfo); 623920e296Sopenharmony_ci } 633920e296Sopenharmony_ci } 643920e296Sopenharmony_ci 653920e296Sopenharmony_ci sort(fileInfos.begin(), fileInfos.end(), [](const auto &a, const auto &b) { 663920e296Sopenharmony_ci return a.filePath < b.filePath; 673920e296Sopenharmony_ci }); 683920e296Sopenharmony_ci if (CompileFiles(fileInfos) != RESTOOL_SUCCESS) { 693920e296Sopenharmony_ci return RESTOOL_ERROR; 703920e296Sopenharmony_ci } 713920e296Sopenharmony_ci return PostCommit(); 723920e296Sopenharmony_ci} 733920e296Sopenharmony_ci 743920e296Sopenharmony_ciuint32_t IResourceCompiler::CompileFiles(const std::vector<FileInfo> &fileInfos) 753920e296Sopenharmony_ci{ 763920e296Sopenharmony_ci for (const auto &fileInfo : fileInfos) { 773920e296Sopenharmony_ci if (CompileSingleFile(fileInfo) != RESTOOL_SUCCESS) { 783920e296Sopenharmony_ci return RESTOOL_ERROR; 793920e296Sopenharmony_ci } 803920e296Sopenharmony_ci } 813920e296Sopenharmony_ci return RESTOOL_SUCCESS; 823920e296Sopenharmony_ci} 833920e296Sopenharmony_ci 843920e296Sopenharmony_ciconst map<int64_t, vector<ResourceItem>> &IResourceCompiler::GetResult() const 853920e296Sopenharmony_ci{ 863920e296Sopenharmony_ci return resourceInfos_; 873920e296Sopenharmony_ci} 883920e296Sopenharmony_ci 893920e296Sopenharmony_ciuint32_t IResourceCompiler::Compile(const FileInfo &fileInfo) 903920e296Sopenharmony_ci{ 913920e296Sopenharmony_ci if (CompileSingleFile(fileInfo) != RESTOOL_SUCCESS) { 923920e296Sopenharmony_ci return RESTOOL_ERROR; 933920e296Sopenharmony_ci } 943920e296Sopenharmony_ci return PostCommit(); 953920e296Sopenharmony_ci} 963920e296Sopenharmony_ci 973920e296Sopenharmony_ciuint32_t IResourceCompiler::CompileForAppend(const FileInfo &fileInfo) 983920e296Sopenharmony_ci{ 993920e296Sopenharmony_ci return CompileSingleFile(fileInfo); 1003920e296Sopenharmony_ci} 1013920e296Sopenharmony_ci 1023920e296Sopenharmony_ciconst map<pair<ResType, string>, vector<ResourceItem>> &IResourceCompiler::GetResourceItems() const 1033920e296Sopenharmony_ci{ 1043920e296Sopenharmony_ci return nameInfos_; 1053920e296Sopenharmony_ci} 1063920e296Sopenharmony_ci 1073920e296Sopenharmony_civoid IResourceCompiler::SetModuleName(const string &moduleName) 1083920e296Sopenharmony_ci{ 1093920e296Sopenharmony_ci moduleName_ = moduleName; 1103920e296Sopenharmony_ci} 1113920e296Sopenharmony_ci 1123920e296Sopenharmony_ciuint32_t IResourceCompiler::CompileSingleFile(const FileInfo &fileInfo) 1133920e296Sopenharmony_ci{ 1143920e296Sopenharmony_ci return RESTOOL_SUCCESS; 1153920e296Sopenharmony_ci} 1163920e296Sopenharmony_ci 1173920e296Sopenharmony_ciuint32_t IResourceCompiler::PostCommit() 1183920e296Sopenharmony_ci{ 1193920e296Sopenharmony_ci IdWorker &idWorker = IdWorker::GetInstance(); 1203920e296Sopenharmony_ci for (const auto &nameInfo : nameInfos_) { 1213920e296Sopenharmony_ci int64_t id = idWorker.GenerateId(nameInfo.first.first, nameInfo.first.second); 1223920e296Sopenharmony_ci if (id < 0) { 1233920e296Sopenharmony_ci cerr << "Error: restype='" << ResourceUtil::ResTypeToString(nameInfo.first.first) << "' name='"; 1243920e296Sopenharmony_ci cerr << nameInfo.first.second << "' id not be defined." << endl; 1253920e296Sopenharmony_ci return RESTOOL_ERROR; 1263920e296Sopenharmony_ci } 1273920e296Sopenharmony_ci resourceInfos_.emplace(id, nameInfo.second); 1283920e296Sopenharmony_ci } 1293920e296Sopenharmony_ci return RESTOOL_SUCCESS; 1303920e296Sopenharmony_ci} 1313920e296Sopenharmony_ci 1323920e296Sopenharmony_cibool IResourceCompiler::MergeResourceItem(const ResourceItem &resourceItem) 1333920e296Sopenharmony_ci{ 1343920e296Sopenharmony_ci string idName = ResourceUtil::GetIdName(resourceItem.GetName(), resourceItem.GetResType()); 1353920e296Sopenharmony_ci if (!ResourceUtil::IsValidName(idName)) { 1363920e296Sopenharmony_ci cerr << "Error: invalid idName '" << idName << "'."<< NEW_LINE_PATH << resourceItem.GetFilePath() << endl; 1373920e296Sopenharmony_ci cerr << SOLUTIONS << endl; 1383920e296Sopenharmony_ci cerr << SOLUTIONS_ARROW << "Modify the name '" << idName << "' to match [a-zA-Z0-9_]." << endl; 1393920e296Sopenharmony_ci return false; 1403920e296Sopenharmony_ci } 1413920e296Sopenharmony_ci auto item = nameInfos_.find(make_pair(resourceItem.GetResType(), idName)); 1423920e296Sopenharmony_ci if (item == nameInfos_.end()) { 1433920e296Sopenharmony_ci nameInfos_[make_pair(resourceItem.GetResType(), idName)].push_back(resourceItem); 1443920e296Sopenharmony_ci return true; 1453920e296Sopenharmony_ci } 1463920e296Sopenharmony_ci 1473920e296Sopenharmony_ci auto ret = find_if(item->second.begin(), item->second.end(), [resourceItem](auto &iter) { 1483920e296Sopenharmony_ci return resourceItem.GetLimitKey() == iter.GetLimitKey(); 1493920e296Sopenharmony_ci }); 1503920e296Sopenharmony_ci if (ret != item->second.end()) { 1513920e296Sopenharmony_ci cerr << "Error: resource '" << idName << "' first declared." << NEW_LINE_PATH << ret->GetFilePath() << endl; 1523920e296Sopenharmony_ci cerr << "but declare again." << NEW_LINE_PATH << resourceItem.GetFilePath() << endl; 1533920e296Sopenharmony_ci return false; 1543920e296Sopenharmony_ci } 1553920e296Sopenharmony_ci 1563920e296Sopenharmony_ci nameInfos_[make_pair(resourceItem.GetResType(), idName)].push_back(resourceItem); 1573920e296Sopenharmony_ci return true; 1583920e296Sopenharmony_ci} 1593920e296Sopenharmony_ci 1603920e296Sopenharmony_cistring IResourceCompiler::GetOutputFolder(const DirectoryInfo &directoryInfo) const 1613920e296Sopenharmony_ci{ 1623920e296Sopenharmony_ci string outputFolder = FileEntry::FilePath(output_).Append(RESOURCES_DIR) 1633920e296Sopenharmony_ci .Append(directoryInfo.limitKey).Append(directoryInfo.fileCluster).GetPath(); 1643920e296Sopenharmony_ci return outputFolder; 1653920e296Sopenharmony_ci} 1663920e296Sopenharmony_ci} 1673920e296Sopenharmony_ci} 1683920e296Sopenharmony_ci} 169