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