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