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