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