• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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