1 /*
2 * Copyright (c) 2021-2025 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 "resource_pack.h"
17 #include <algorithm>
18 #include <cstdint>
19 #include <iomanip>
20 #include "file_entry.h"
21 #include "file_manager.h"
22 #include "header.h"
23 #include "resource_check.h"
24 #include "resource_merge.h"
25 #include "resource_table.h"
26 #include "compression_parser.h"
27 #include "binary_file_packer.h"
28 #include "resource_packer_factory.h"
29
30 namespace OHOS {
31 namespace Global {
32 namespace Restool {
33 using namespace std;
ResourcePack(const PackageParser & packageParser)34 ResourcePack::ResourcePack(const PackageParser &packageParser):packageParser_(packageParser)
35 {}
36
Package()37 uint32_t ResourcePack::Package()
38 {
39 uint32_t errorCode = RESTOOL_SUCCESS;
40 if (!packageParser_.GetAppend().empty()) {
41 errorCode = PackAppend();
42 } else if (packageParser_.GetCombine()) {
43 errorCode = PackCombine();
44 } else {
45 if (packageParser_.IsOverlap()) {
46 packType_ = PackType::OVERLAP;
47 }
48 unique_ptr<ResourcePack> resourcePacker =
49 ResourcePackerFactory::CreatePacker(packType_, packageParser_);
50 if (!resourcePacker) {
51 return RESTOOL_ERROR;
52 }
53 errorCode = resourcePacker->Pack();
54 }
55 if (errorCode == RESTOOL_SUCCESS) {
56 ShowPackSuccess();
57 }
58 return errorCode;
59 }
60
InitCompression()61 uint32_t ResourcePack::InitCompression()
62 {
63 if (!packageParser_.GetCompressionPath().empty()) {
64 auto compressionMgr = CompressionParser::GetCompressionParser(packageParser_.GetCompressionPath());
65 compressionMgr->SetOutPath(packageParser_.GetOutput());
66 if (compressionMgr->Init() != RESTOOL_SUCCESS) {
67 return RESTOOL_ERROR;
68 }
69 }
70 return RESTOOL_SUCCESS;
71 }
72
73 // below private founction
InitResourcePack()74 uint32_t ResourcePack::InitResourcePack()
75 {
76 InitHeaderCreater();
77 if (InitCompression() != RESTOOL_SUCCESS) {
78 return RESTOOL_ERROR;
79 }
80
81 if (InitOutput() != RESTOOL_SUCCESS) {
82 return RESTOOL_ERROR;
83 }
84
85 if (InitConfigJson() != RESTOOL_SUCCESS) {
86 return RESTOOL_ERROR;
87 }
88
89 if (InitModule() != RESTOOL_SUCCESS) {
90 return RESTOOL_ERROR;
91 }
92 if (ThreadPool::GetInstance().Start(packageParser_.GetThreadCount()) != RESTOOL_SUCCESS) {
93 return RESTOOL_ERROR;
94 };
95 return RESTOOL_SUCCESS;
96 }
97
InitModule()98 uint32_t ResourcePack::InitModule()
99 {
100 ResourceIdCluster hapType = ResourceIdCluster::RES_ID_APP;
101 string packageName = packageParser_.GetPackageName();
102 if (packageName == "ohos.global.systemres") {
103 hapType = ResourceIdCluster::RES_ID_SYS;
104 }
105
106 moduleName_ = configJson_.GetModuleName();
107 FileManager::GetInstance().SetModuleName(moduleName_);
108 vector<string> moduleNames = packageParser_.GetModuleNames();
109 IdWorker &idWorker = IdWorker::GetInstance();
110 int64_t startId = static_cast<int64_t>(packageParser_.GetStartId());
111 if (startId > 0) {
112 return idWorker.Init(hapType, startId);
113 }
114
115 if (moduleNames.empty()) {
116 return idWorker.Init(hapType);
117 } else {
118 sort(moduleNames.begin(), moduleNames.end());
119 auto it = find_if(moduleNames.begin(), moduleNames.end(), [this](auto iter) {
120 return moduleName_ == iter;
121 });
122 if (it == moduleNames.end()) {
123 string buffer("[");
124 for_each(moduleNames.begin(), moduleNames.end(), [&buffer](const auto &iter) {
125 buffer.append("\"" + iter + "\"").append(",");
126 });
127 buffer.pop_back();
128 buffer.append("]");
129 PrintError(GetError(ERR_CODE_MODULE_NAME_NOT_FOUND).FormatCause(moduleName_.c_str(), buffer.c_str())
130 .SetPosition(configJson_.GetConfigFilePath()));
131 return RESTOOL_ERROR;
132 }
133
134 startId = ((it - moduleNames.begin()) + 1) * 0x01000000;
135 if (startId >= 0x07000000) {
136 startId = startId + 0x01000000;
137 }
138 return idWorker.Init(hapType, startId);
139 }
140 return RESTOOL_SUCCESS;
141 }
142
InitHeaderCreater()143 void ResourcePack::InitHeaderCreater()
144 {
145 using namespace placeholders;
146 headerCreaters_.emplace(".txt", bind(&ResourcePack::GenerateTextHeader, this, _1));
147 headerCreaters_.emplace(".js", bind(&ResourcePack::GenerateJsHeader, this, _1));
148 headerCreaters_.emplace(".h", bind(&ResourcePack::GenerateCplusHeader, this, _1));
149 }
150
InitOutput() const151 uint32_t ResourcePack::InitOutput() const
152 {
153 bool forceWrite = packageParser_.GetForceWrite();
154 bool combine = packageParser_.GetCombine();
155 string output = packageParser_.GetOutput();
156 string resourcesPath = FileEntry::FilePath(output).Append(RESOURCES_DIR).GetPath();
157 if (ResourceUtil::FileExist(resourcesPath)) {
158 if (!forceWrite) {
159 PrintError(GetError(ERR_CODE_OUTPUT_EXIST).SetPosition(resourcesPath));
160 return RESTOOL_ERROR;
161 }
162
163 if (!ResourceUtil::RmoveAllDir(resourcesPath)) {
164 return combine ? RESTOOL_SUCCESS : RESTOOL_ERROR;
165 }
166 }
167 return RESTOOL_SUCCESS;
168 }
169
GenerateHeader() const170 uint32_t ResourcePack::GenerateHeader() const
171 {
172 auto headerPaths = packageParser_.GetResourceHeaders();
173 string textPath = FileEntry::FilePath(packageParser_.GetOutput()).Append("ResourceTable.txt").GetPath();
174 headerPaths.push_back(textPath);
175 for (const auto &headerPath : headerPaths) {
176 string extension = FileEntry::FilePath(headerPath).GetExtension();
177 auto it = headerCreaters_.find(extension);
178 if (it == headerCreaters_.end()) {
179 cout << "Warning: don't support header file format '" << headerPath << "'" << endl;
180 continue;
181 }
182 if (it->second(headerPath) != RESTOOL_SUCCESS) {
183 return RESTOOL_ERROR;
184 }
185 }
186 return RESTOOL_SUCCESS;
187 }
188
InitConfigJson()189 uint32_t ResourcePack::InitConfigJson()
190 {
191 string config = packageParser_.GetConfig();
192 if (config.empty()) {
193 if (packageParser_.GetInputs().size() > 1) {
194 PrintError(ERR_CODE_CONFIG_JSON_MISSING);
195 return RESTOOL_ERROR;
196 }
197 config = ResourceUtil::GetMainPath(packageParser_.GetInputs()[0]).Append(CONFIG_JSON).GetPath();
198 if (!ResourceUtil::FileExist(config)) {
199 config = ResourceUtil::GetMainPath(packageParser_.GetInputs()[0]).Append(MODULE_JSON).GetPath();
200 }
201 }
202
203 if (FileEntry::FilePath(config).GetFilename() == MODULE_JSON) {
204 ConfigParser::SetUseModule();
205 }
206 configJson_ = ConfigParser(config);
207 if (configJson_.Init() != RESTOOL_SUCCESS) {
208 return RESTOOL_ERROR;
209 }
210 return RESTOOL_SUCCESS;
211 }
212
GenerateTextHeader(const string & headerPath) const213 uint32_t ResourcePack::GenerateTextHeader(const string &headerPath) const
214 {
215 Header textHeader(headerPath);
216 bool first = true;
217 uint32_t result = textHeader.Create([](stringstream &buffer) {},
218 [&first](stringstream &buffer, const ResourceId& resourceId) {
219 if (first) {
220 first = false;
221 } else {
222 buffer << "\n";
223 }
224 buffer << resourceId.type << " " << resourceId.name;
225 buffer << " 0x" << hex << setw(8) << setfill('0') << resourceId.id;
226 }, [](stringstream &buffer) {});
227 if (result != RESTOOL_SUCCESS) {
228 return RESTOOL_ERROR;
229 }
230 return RESTOOL_SUCCESS;
231 }
232
GenerateCplusHeader(const string & headerPath) const233 uint32_t ResourcePack::GenerateCplusHeader(const string &headerPath) const
234 {
235 Header cplusHeader(headerPath);
236 uint32_t result = cplusHeader.Create([](stringstream &buffer) {
237 buffer << Header::LICENSE_HEADER << "\n";
238 buffer << "#ifndef RESOURCE_TABLE_H\n";
239 buffer << "#define RESOURCE_TABLE_H\n\n";
240 buffer << "#include<stdint.h>\n\n";
241 buffer << "namespace OHOS {\n";
242 }, [](stringstream &buffer, const ResourceId& resourceId) {
243 string name = resourceId.type + "_" + resourceId.name;
244 transform(name.begin(), name.end(), name.begin(), ::toupper);
245 buffer << "const int32_t " << name << " = ";
246 buffer << "0x" << hex << setw(8) << setfill('0') << resourceId.id << ";\n";
247 }, [](stringstream &buffer) {
248 buffer << "}\n";
249 buffer << "#endif";
250 });
251 return result;
252 }
253
GenerateJsHeader(const std::string & headerPath) const254 uint32_t ResourcePack::GenerateJsHeader(const std::string &headerPath) const
255 {
256 Header JsHeader(headerPath);
257 string itemType;
258 uint32_t result = JsHeader.Create([](stringstream &buffer) {
259 buffer << Header::LICENSE_HEADER << "\n";
260 buffer << "export default {\n";
261 }, [&itemType](stringstream &buffer, const ResourceId& resourceId) {
262 if (itemType != resourceId.type) {
263 if (!itemType.empty()) {
264 buffer << "\n" << " " << "},\n";
265 }
266 buffer << " " << resourceId.type << " : {\n";
267 itemType = resourceId.type;
268 } else {
269 buffer << ",\n";
270 }
271 buffer << " " << resourceId.name << " : " << resourceId.id;
272 }, [](stringstream &buffer) {
273 buffer << "\n" << " " << "}\n";
274 buffer << "}\n";
275 });
276 return result;
277 }
278
GenerateConfigJson()279 uint32_t ResourcePack::GenerateConfigJson()
280 {
281 if (configJson_.ParseRefence() != RESTOOL_SUCCESS) {
282 return RESTOOL_ERROR;
283 }
284 string outputPath = FileEntry::FilePath(packageParser_.GetOutput())
285 .Append(ConfigParser::GetConfigName()).GetPath();
286 return configJson_.Save(outputPath);
287 }
288
CheckConfigJson()289 void ResourcePack::CheckConfigJson()
290 {
291 ResourceCheck resourceCheck(configJson_.GetCheckNode());
292 resourceCheck.CheckConfigJson();
293 }
294
ScanResources(const vector<string> & inputs,const string & output)295 uint32_t ResourcePack::ScanResources(const vector<string> &inputs, const string &output)
296 {
297 auto &fileManager = FileManager::GetInstance();
298 fileManager.SetModuleName(moduleName_);
299 if (fileManager.ScanModules(inputs, output, configJson_.IsHar()) != RESTOOL_SUCCESS) {
300 return RESTOOL_ERROR;
301 }
302 return RESTOOL_SUCCESS;
303 }
304
Pack()305 uint32_t ResourcePack::Pack()
306 {
307 cout << "Info: Pack: normal pack mode" << endl;
308
309 if (InitResourcePack() != RESTOOL_SUCCESS) {
310 return RESTOOL_ERROR;
311 }
312
313 ResourceMerge resourceMerge;
314 if (resourceMerge.Init(packageParser_) != RESTOOL_SUCCESS) {
315 return RESTOOL_ERROR;
316 }
317
318 BinaryFilePacker rawFilePacker(packageParser_, moduleName_);
319 std::future<uint32_t> copyFuture = rawFilePacker.CopyBinaryFileAsync(resourceMerge.GetInputs());
320
321 if (PackResources(resourceMerge) != RESTOOL_SUCCESS) {
322 rawFilePacker.StopCopy();
323 return RESTOOL_ERROR;
324 }
325
326 if (copyFuture.get() != RESTOOL_SUCCESS) {
327 return RESTOOL_ERROR;
328 }
329 return RESTOOL_SUCCESS;
330 }
331
PackResources(const ResourceMerge & resourceMerge)332 uint32_t ResourcePack::PackResources(const ResourceMerge &resourceMerge)
333 {
334 if (ScanResources(resourceMerge.GetInputs(), packageParser_.GetOutput()) != RESTOOL_SUCCESS) {
335 return RESTOOL_ERROR;
336 }
337
338 if (GenerateHeader() != RESTOOL_SUCCESS) {
339 return RESTOOL_ERROR;
340 }
341
342 if (GenerateConfigJson() != RESTOOL_SUCCESS) {
343 return RESTOOL_ERROR;
344 }
345
346 if (!FileManager::GetInstance().ScaleIcons(packageParser_.GetOutput(), configJson_.GetCheckNode())) {
347 return RESTOOL_ERROR;
348 }
349
350 if (packageParser_.GetIconCheck()) {
351 CheckConfigJson();
352 }
353
354 ResourceTable resourceTable(configJson_.isSupportNewModule());
355 if (!packageParser_.GetDependEntry().empty()) {
356 if (HandleFeature() != RESTOOL_SUCCESS) {
357 return RESTOOL_ERROR;
358 }
359 if (GenerateHeader() != RESTOOL_SUCCESS) {
360 return RESTOOL_ERROR;
361 }
362 }
363
364 if (resourceTable.CreateResourceTable() != RESTOOL_SUCCESS) {
365 return RESTOOL_ERROR;
366 }
367 return RESTOOL_SUCCESS;
368 }
369
HandleFeature()370 uint32_t ResourcePack::HandleFeature()
371 {
372 string output = packageParser_.GetOutput();
373 string featureDependEntry = packageParser_.GetDependEntry();
374 if (featureDependEntry.empty()) {
375 return RESTOOL_SUCCESS;
376 }
377 string jsonFile = FileEntry::FilePath(featureDependEntry).Append(CONFIG_JSON).GetPath();
378 ConfigParser entryJson(jsonFile);
379 entryJson.SetDependEntry(true);
380 if (entryJson.Init() != RESTOOL_SUCCESS) {
381 return RESTOOL_ERROR;
382 }
383
384 int64_t labelId = entryJson.GetAbilityLabelId();
385 int64_t iconId = entryJson.GetAbilityIconId();
386 if (labelId <= 0 || iconId <= 0) {
387 return RESTOOL_ERROR;
388 }
389 string path = FileEntry::FilePath(featureDependEntry).Append(RESOURCE_INDEX_FILE).GetPath();
390 map<int64_t, vector<ResourceItem>> resInfoLocal;
391 ResourceTable resourceTable;
392 if (resourceTable.LoadResTable(path, resInfoLocal) != RESTOOL_SUCCESS) {
393 return RESTOOL_ERROR;
394 }
395 jsonFile = FileEntry::FilePath(output).Append(CONFIG_JSON).GetPath();
396 ConfigParser config(jsonFile);
397 if (config.Init() != RESTOOL_SUCCESS) {
398 return RESTOOL_ERROR;
399 }
400 vector<ResourceItem> items;
401 if (FindResourceItems(resInfoLocal, items, labelId) != RESTOOL_SUCCESS ||
402 HandleLabel(items, config) != RESTOOL_SUCCESS) {
403 return RESTOOL_ERROR;
404 }
405 items.clear();
406 if (FindResourceItems(resInfoLocal, items, iconId) != RESTOOL_SUCCESS ||
407 HandleIcon(items, config) != RESTOOL_SUCCESS) {
408 return RESTOOL_ERROR;
409 }
410 string outputPath = FileEntry::FilePath(output).Append(ConfigParser::GetConfigName()).GetPath();
411 if (config.Save(outputPath) != RESTOOL_SUCCESS) {
412 return RESTOOL_ERROR;
413 }
414 entryJson.SetDependEntry(false);
415 return RESTOOL_SUCCESS;
416 }
417
FindResourceItems(const map<int64_t,vector<ResourceItem>> & resInfoLocal,vector<ResourceItem> & items,int64_t id) const418 uint32_t ResourcePack::FindResourceItems(const map<int64_t, vector<ResourceItem>> &resInfoLocal,
419 vector<ResourceItem> &items, int64_t id) const
420 {
421 auto ret = resInfoLocal.find(id);
422 if (ret == resInfoLocal.end()) {
423 string msg = "the id '" + std::to_string(id) + "' not found";
424 PrintError(GetError(ERR_CODE_INVALID_RESOURCE_INDEX).FormatCause(msg.c_str()));
425 return RESTOOL_ERROR;
426 }
427 ResType type = ResType::INVALID_RES_TYPE;
428 items = ret->second;
429 if (items.empty()) {
430 string msg = "the items of id '" + std::to_string(id) + "' is empty";
431 PrintError(GetError(ERR_CODE_INVALID_RESOURCE_INDEX).FormatCause(msg.c_str()));
432 return RESTOOL_ERROR;
433 }
434 for (auto &it : items) {
435 if (type == ResType::INVALID_RES_TYPE) {
436 type = it.GetResType();
437 }
438 if (type != it.GetResType()) {
439 string typePre = ResourceUtil::ResTypeToString(type);
440 string typeCur = ResourceUtil::ResTypeToString(it.GetResType());
441 string msg = "invalid restype '" + typePre + "', expected type is '" + typeCur + "'";
442 PrintError(GetError(ERR_CODE_INVALID_RESOURCE_INDEX).FormatCause(msg.c_str()));
443 return RESTOOL_ERROR;
444 }
445 }
446 return RESTOOL_SUCCESS;
447 }
448
HandleLabel(vector<ResourceItem> & items,ConfigParser & config) const449 uint32_t ResourcePack::HandleLabel(vector<ResourceItem> &items, ConfigParser &config) const
450 {
451 int64_t nextId = 0;
452 string idName;
453 for (auto it : items) {
454 if (it.GetResType() != ResType::STRING) {
455 string typeCur = ResourceUtil::ResTypeToString(it.GetResType());
456 string typeExpect = ResourceUtil::ResTypeToString(ResType::STRING);
457 string msg = "invalid restype '" + typeCur + "', expected type is '" + typeExpect + "'";
458 PrintError(GetError(ERR_CODE_INVALID_RESOURCE_INDEX).FormatCause(msg.c_str()));
459 return RESTOOL_ERROR;
460 }
461 idName = it.GetName() + "_entry";
462 it.SetName(idName);
463 string data(reinterpret_cast<const char *>(it.GetData()));
464 if (it.GetDataLength() - 1 < 0) {
465 return RESTOOL_ERROR;
466 }
467 if (!it.SetData(reinterpret_cast<const int8_t *>(data.c_str()), it.GetDataLength() - 1)) {
468 return RESTOOL_ERROR;
469 }
470 if (nextId <= 0) {
471 nextId = IdWorker::GetInstance().GenerateId(ResType::STRING, idName);
472 }
473 SaveResourceItem(it, nextId);
474 }
475 string label = "$string:" +idName;
476 config.SetAppLabel(label, nextId);
477 return RESTOOL_SUCCESS;
478 }
479
CopyIcon(string & dataPath,const string & idName,string & fileName) const480 bool ResourcePack::CopyIcon(string &dataPath, const string &idName, string &fileName) const
481 {
482 string featureDependEntry = packageParser_.GetDependEntry();
483 string source = FileEntry::FilePath(featureDependEntry).Append(dataPath).GetPath();
484 string suffix = FileEntry::FilePath(source).GetExtension();
485 fileName = idName + suffix;
486 string output = packageParser_.GetOutput();
487 #ifdef _WIN32
488 ResourceUtil::StringReplace(dataPath, SEPARATOR, WIN_SEPARATOR);
489 #endif
490 string dstDir = FileEntry::FilePath(output).Append(dataPath).GetParent().GetPath();
491 string dst = FileEntry::FilePath(dstDir).Append(fileName).GetPath();
492 if (!ResourceUtil::CreateDirs(dstDir)) {
493 return false;
494 }
495 if (!ResourceUtil::CopyFileInner(source, dst)) {
496 return false;
497 }
498 return true;
499 }
500
HandleIcon(vector<ResourceItem> & items,ConfigParser & config) const501 uint32_t ResourcePack::HandleIcon(vector<ResourceItem> &items, ConfigParser &config) const
502 {
503 int64_t nextId = 0;
504 string idName;
505 for (auto it : items) {
506 if (it.GetResType() != ResType::MEDIA) {
507 string typeCur = ResourceUtil::ResTypeToString(it.GetResType());
508 string typeExpect = ResourceUtil::ResTypeToString(ResType::MEDIA);
509 string msg = "invalid restype '" + typeCur + "', expected type is '" + typeExpect + "'";
510 PrintError(GetError(ERR_CODE_INVALID_RESOURCE_INDEX).FormatCause(msg.c_str()));
511 return RESTOOL_ERROR;
512 }
513 string dataPath(reinterpret_cast<const char *>(it.GetData()));
514 string::size_type pos = dataPath.find_first_of(SEPARATOR);
515 if (pos == string::npos) {
516 PrintError(GetError(ERR_CODE_INVALID_RESOURCE_PATH).FormatCause(dataPath.c_str(), "missing separator"));
517 return RESTOOL_ERROR;
518 }
519 dataPath = dataPath.substr(pos + 1);
520 idName = it.GetName() + "_entry";
521 string fileName;
522 if (!CopyIcon(dataPath, idName, fileName)) {
523 return RESTOOL_ERROR;
524 }
525 string data = FileEntry::FilePath(moduleName_).Append(dataPath).GetParent().Append(fileName).GetPath();
526 ResourceUtil::StringReplace(data, WIN_SEPARATOR, SEPARATOR);
527 ResourceItem resourceItem(fileName, it.GetKeyParam(), ResType::MEDIA);
528 resourceItem.SetLimitKey(it.GetLimitKey());
529 if (!resourceItem.SetData(reinterpret_cast<const int8_t *>(data.c_str()), data.length())) {
530 return RESTOOL_ERROR;
531 }
532 if (nextId <= 0) {
533 nextId = IdWorker::GetInstance().GenerateId(ResType::MEDIA, idName);
534 }
535 SaveResourceItem(resourceItem, nextId);
536 }
537 string icon = "$media:" + idName;
538 config.SetAppIcon(icon, nextId);
539 return RESTOOL_SUCCESS;
540 }
541
SaveResourceItem(const ResourceItem & resourceItem,int64_t nextId) const542 void ResourcePack::SaveResourceItem(const ResourceItem &resourceItem, int64_t nextId) const
543 {
544 map<int64_t, vector<ResourceItem>> resInfo;
545 vector<ResourceItem> vet;
546 vet.push_back(resourceItem);
547 resInfo.insert(make_pair(nextId, vet));
548 FileManager &fileManager = FileManager::GetInstance();
549 fileManager.MergeResourceItem(resInfo);
550 }
551
PackAppend()552 uint32_t ResourcePack::PackAppend()
553 {
554 ResourceAppend resourceAppend(packageParser_);
555 if (!packageParser_.GetAppend().empty()) {
556 return resourceAppend.Append();
557 }
558 return RESTOOL_SUCCESS;
559 }
560
PackCombine()561 uint32_t ResourcePack::PackCombine()
562 {
563 if (InitResourcePack() != RESTOOL_SUCCESS) {
564 return RESTOOL_ERROR;
565 }
566
567 ResourceAppend resourceAppend(packageParser_);
568 if (resourceAppend.Combine() != RESTOOL_SUCCESS) {
569 return RESTOOL_ERROR;
570 }
571
572 if (GenerateConfigJson() != RESTOOL_SUCCESS) {
573 return RESTOOL_ERROR;
574 }
575
576 if (packageParser_.GetIconCheck()) {
577 CheckConfigJsonForCombine(resourceAppend);
578 }
579
580 if (GenerateHeader() != RESTOOL_SUCCESS) {
581 return RESTOOL_ERROR;
582 }
583 return RESTOOL_SUCCESS;
584 }
585
CheckConfigJsonForCombine(ResourceAppend & resourceAppend)586 void ResourcePack::CheckConfigJsonForCombine(ResourceAppend &resourceAppend)
587 {
588 ResourceCheck resourceCheck(configJson_.GetCheckNode(), make_shared<ResourceAppend>(resourceAppend));
589 resourceCheck.CheckConfigJsonForCombine();
590 }
591
ShowPackSuccess()592 void ResourcePack::ShowPackSuccess()
593 {
594 cout << "Info: restool resources compile success." << endl;
595 if (CompressionParser::GetCompressionParser()->GetMediaSwitch()) {
596 cout << CompressionParser::GetCompressionParser()->PrintTransMessage() << endl;
597 }
598 }
599 }
600 }
601 }
602