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)28 GenericCompiler::GenericCompiler(ResType type, const string &output)
29 : IResourceCompiler(type, output)
30 {
31 }
~GenericCompiler()32 GenericCompiler::~GenericCompiler()
33 {
34 }
35
CompileFiles(const std::vector<FileInfo> &fileInfos)36 uint32_t GenericCompiler::CompileFiles(const std::vector<FileInfo> &fileInfos)
37 {
38 cout << "Info: GenericCompiler::CompileFiles" << endl;
39 ThreadPool pool(THREAD_POOL_SIZE);
40 pool.Start();
41 std::vector<std::future<uint32_t>> results;
42 for (const auto &fileInfo : fileInfos) {
43 auto taskFunc = [this](const FileInfo &fileInfo) { return this->CompileSingleFile(fileInfo); };
44 results.push_back(pool.Enqueue(taskFunc, fileInfo));
45 }
46 for (auto &ret : results) {
47 if (ret.get() != RESTOOL_SUCCESS) {
48 return RESTOOL_ERROR;
49 }
50 }
51 return RESTOOL_SUCCESS;
52 }
53
CompileSingleFile(const FileInfo &fileInfo)54 uint32_t GenericCompiler::CompileSingleFile(const FileInfo &fileInfo)
55 {
56 if (IsIgnore(fileInfo)) {
57 return RESTOOL_SUCCESS;
58 }
59
60 string output = "";
61 if (!CopyMediaFile(fileInfo, output)) {
62 return RESTOOL_ERROR;
63 }
64
65 if (!PostMediaFile(fileInfo, output)) {
66 return RESTOOL_ERROR;
67 }
68 return RESTOOL_SUCCESS;
69 }
70
PostMediaFile(const FileInfo &fileInfo, const std::string &output)71 bool GenericCompiler::PostMediaFile(const FileInfo &fileInfo, const std::string &output)
72 {
73 std::lock_guard<std::mutex> lock(mutex_);
74 ResourceItem resourceItem(fileInfo.filename, fileInfo.keyParams, type_);
75 resourceItem.SetFilePath(fileInfo.filePath);
76 resourceItem.SetLimitKey(fileInfo.limitKey);
77
78 auto index = output.find_last_of(SEPARATOR_FILE);
79 if (index == string::npos) {
80 cerr << "Error: invalid output path." << NEW_LINE_PATH << output << endl;
81 return false;
82 }
83 string data = output.substr(index + 1);
84 data = moduleName_ + SEPARATOR + RESOURCES_DIR + SEPARATOR + \
85 fileInfo.limitKey + SEPARATOR + fileInfo.fileCluster + SEPARATOR + data;
86 if (!resourceItem.SetData(reinterpret_cast<const int8_t *>(data.c_str()), data.length())) {
87 cerr << "Error: resource item set data fail, data: " << data << NEW_LINE_PATH << fileInfo.filePath << endl;
88 return false;
89 }
90 return MergeResourceItem(resourceItem);
91 }
92
GetOutputFilePath(const FileInfo &fileInfo) const93 string GenericCompiler::GetOutputFilePath(const FileInfo &fileInfo) const
94 {
95 string outputFolder = GetOutputFolder(fileInfo);
96 string outputFilePath = FileEntry::FilePath(outputFolder).Append(fileInfo.filename).GetPath();
97 return outputFilePath;
98 }
99
IsIgnore(const FileInfo &fileInfo)100 bool GenericCompiler::IsIgnore(const FileInfo &fileInfo)
101 {
102 std::lock_guard<std::mutex> lock(mutex_);
103 string output = GetOutputFilePath(fileInfo);
104 if (!g_resourceSet.emplace(output).second) {
105 cerr << "Warning: '" << fileInfo.filePath << "' is defined repeatedly." << endl;
106 return true;
107 }
108 return false;
109 }
110
CopyMediaFile(const FileInfo &fileInfo, std::string &output)111 bool GenericCompiler::CopyMediaFile(const FileInfo &fileInfo, std::string &output)
112 {
113 string outputFolder = GetOutputFolder(fileInfo);
114 if (!ResourceUtil::CreateDirs(outputFolder)) {
115 cerr << "Error: CopyMediaFile create dirs failed." << NEW_LINE_PATH << outputFolder << endl;
116 return false;
117 }
118 output = GetOutputFilePath(fileInfo);
119 if (moduleName_ == "har" || type_ != ResType::MEDIA) {
120 return ResourceUtil::CopyFileInner(fileInfo.filePath, output);
121 } else {
122 return CompressionParser::GetCompressionParser()->CopyAndTranscode(fileInfo.filePath, output);
123 }
124 }
125 }
126 }
127 }