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