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 "generic_compiler.h"
17 #include <iostream>
18 #include "file_entry.h"
19 #include "resource_util.h"
20 #include "restool_errors.h"
21 #include "compression_parser.h"
22 #include "thread_pool.h"
23
24 namespace OHOS {
25 namespace Global {
26 namespace Restool {
27 using namespace std;
GenericCompiler(ResType type,const string & output,bool isOverlap)28 GenericCompiler::GenericCompiler(ResType type, const string &output, bool isOverlap)
29 : IResourceCompiler(type, output, isOverlap)
30 {
31 }
32
~GenericCompiler()33 GenericCompiler::~GenericCompiler()
34 {
35 }
36
CompileFiles(const std::vector<FileInfo> & fileInfos)37 uint32_t GenericCompiler::CompileFiles(const std::vector<FileInfo> &fileInfos)
38 {
39 cout << "Info: GenericCompiler::CompileFiles" << endl;
40 std::vector<std::future<uint32_t>> results;
41 for (const auto &fileInfo : fileInfos) {
42 auto taskFunc = [this](const FileInfo &fileInfo) { return this->CompileSingleFile(fileInfo); };
43 results.push_back(ThreadPool::GetInstance().Enqueue(taskFunc, fileInfo));
44 }
45 for (auto &ret : results) {
46 if (ret.get() != RESTOOL_SUCCESS) {
47 return RESTOOL_ERROR;
48 }
49 }
50 return RESTOOL_SUCCESS;
51 }
52
CompileSingleFile(const FileInfo & fileInfo)53 uint32_t GenericCompiler::CompileSingleFile(const FileInfo &fileInfo)
54 {
55 if (IsIgnore(fileInfo)) {
56 return RESTOOL_SUCCESS;
57 }
58
59 string output = "";
60 if (!CopyMediaFile(fileInfo, output)) {
61 return RESTOOL_ERROR;
62 }
63
64 if (!PostMediaFile(fileInfo, output)) {
65 return RESTOOL_ERROR;
66 }
67 return RESTOOL_SUCCESS;
68 }
69
PostMediaFile(const FileInfo & fileInfo,const std::string & output)70 bool GenericCompiler::PostMediaFile(const FileInfo &fileInfo, const std::string &output)
71 {
72 std::lock_guard<std::mutex> lock(mutex_);
73 ResourceItem resourceItem(fileInfo.filename, fileInfo.keyParams, type_);
74 resourceItem.SetFilePath(fileInfo.filePath);
75 resourceItem.SetLimitKey(fileInfo.limitKey);
76
77 auto index = output.find_last_of(SEPARATOR_FILE);
78 if (index == string::npos) {
79 PrintError(GetError(ERR_CODE_INVALID_RESOURCE_PATH).FormatCause(output.c_str(), "missing separator"));
80 return false;
81 }
82 string data = output.substr(index + 1);
83 data = moduleName_ + SEPARATOR + RESOURCES_DIR + SEPARATOR + \
84 fileInfo.limitKey + SEPARATOR + fileInfo.fileCluster + SEPARATOR + data;
85 if (!resourceItem.SetData(reinterpret_cast<const int8_t *>(data.c_str()), data.length())) {
86 std::string msg = "item data is null, resource name: " + resourceItem.GetName();
87 PrintError(GetError(ERR_CODE_UNDEFINED_ERROR).FormatCause(msg.c_str()).SetPosition(fileInfo.filePath));
88 return false;
89 }
90
91 if (isOverlap_) {
92 resourceItem.MarkCoverable();
93 }
94
95 return MergeResourceItem(resourceItem);
96 }
97
GetOutputFilePath(const FileInfo & fileInfo) const98 string GenericCompiler::GetOutputFilePath(const FileInfo &fileInfo) const
99 {
100 string outputFolder = GetOutputFolder(fileInfo);
101 string outputFilePath = FileEntry::FilePath(outputFolder).Append(fileInfo.filename).GetPath();
102 return outputFilePath;
103 }
104
IsIgnore(const FileInfo & fileInfo)105 bool GenericCompiler::IsIgnore(const FileInfo &fileInfo)
106 {
107 lock_guard<mutex> lock(mutex_);
108 string output = GetOutputFilePath(fileInfo);
109 if (g_hapResourceSet.count(output)) {
110 g_hapResourceSet.erase(output);
111 } else if (!g_resourceSet.emplace(output).second) {
112 cout << "Warning: '" << fileInfo.filePath << "' is defined repeatedly." << endl;
113 return true;
114 }
115 return false;
116 }
117
CopyMediaFile(const FileInfo & fileInfo,std::string & output)118 bool GenericCompiler::CopyMediaFile(const FileInfo &fileInfo, std::string &output)
119 {
120 string outputFolder = GetOutputFolder(fileInfo);
121 if (!ResourceUtil::CreateDirs(outputFolder)) {
122 return false;
123 }
124 output = GetOutputFilePath(fileInfo);
125 if (moduleName_ == "har" || type_ != ResType::MEDIA) {
126 return ResourceUtil::CopyFileInner(fileInfo.filePath, output);
127 } else {
128 return CompressionParser::GetCompressionParser()->CopyAndTranscode(fileInfo.filePath, output);
129 }
130 }
131 }
132 }
133 }