• 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 "file_manager.h"
17 #include <algorithm>
18 #include "compression_parser.h"
19 #include <iostream>
20 #include "factory_resource_compiler.h"
21 #include "file_entry.h"
22 #include "key_parser.h"
23 #include "reference_parser.h"
24 #include "resource_directory.h"
25 #include "resource_util.h"
26 #include "restool_errors.h"
27 #include "resource_module.h"
28 
29 namespace OHOS {
30 namespace Global {
31 namespace Restool {
32 using namespace std;
ScanModules(const vector<string> & inputs,const string & output,const bool isHar)33 uint32_t FileManager::ScanModules(const vector<string> &inputs, const string &output, const bool isHar)
34 {
35     vector<pair<ResType, string>> noBaseResource;
36     for (auto input : inputs) {
37         if (ScanModule(input, output) != RESTOOL_SUCCESS) {
38             return RESTOOL_ERROR;
39         }
40         CheckAllItems(noBaseResource);
41     }
42     if (!noBaseResource.empty()) {
43         ResourceUtil::PrintWarningMsg(noBaseResource);
44     }
45     return isHar ? RESTOOL_SUCCESS : ParseReference(output);
46 }
47 
MergeResourceItem(const map<int64_t,vector<ResourceItem>> & resourceInfos)48 uint32_t FileManager::MergeResourceItem(const map<int64_t, vector<ResourceItem>> &resourceInfos)
49 {
50     return ResourceModule::MergeResourceItem(items_, resourceInfos);
51 }
52 
53 // below private founction
ScanModule(const string & input,const string & output)54 uint32_t FileManager::ScanModule(const string &input, const string &output)
55 {
56     ResourceModule resourceModule(input, output, moduleName_);
57     if (resourceModule.ScanResource() != RESTOOL_SUCCESS) {
58         return RESTOOL_ERROR;
59     }
60     MergeResourceItem(resourceModule.GetOwner());
61     return RESTOOL_SUCCESS;
62 }
63 
ParseReference(const string & output)64 uint32_t FileManager::ParseReference(const string &output)
65 {
66     ReferenceParser referenceParser;
67     if (referenceParser.ParseRefInResources(items_, output) != RESTOOL_SUCCESS) {
68         return RESTOOL_ERROR;
69     }
70     return RESTOOL_SUCCESS;
71 }
72 
CheckAllItems(vector<pair<ResType,string>> & noBaseResource)73 void FileManager::CheckAllItems(vector<pair<ResType, string>> &noBaseResource)
74 {
75     for (const auto &item : items_) {
76         bool found = any_of(item.second.begin(), item.second.end(), [](const auto &iter) {
77             return iter.GetLimitKey() == "base";
78         });
79         if (!found) {
80             auto firstItem = item.second.front();
81             bool ret = any_of(noBaseResource.begin(), noBaseResource.end(), [firstItem](const auto &iterItem) {
82                 return (firstItem.GetResType() == iterItem.first)  &&
83                     (firstItem.GetName() == iterItem.second);
84             });
85             if (!ret) {
86                 noBaseResource.push_back(make_pair(firstItem.GetResType(), firstItem.GetName()));
87             }
88         }
89     }
90 }
91 
ScaleIcons(const string & output,const std::map<std::string,std::set<uint32_t>> & iconMap)92 bool FileManager::ScaleIcons(const string &output, const std::map<std::string, std::set<uint32_t>> &iconMap)
93 {
94     if (!CompressionParser::GetCompressionParser()->ScaleIconEnable()) {
95         cout << "Info: scale icon is not enable." << endl;
96         return true;
97     }
98     std::set<int64_t> allIconIds;
99     for (auto &it : iconMap) {
100         if (it.first != "icon") {
101             continue;
102         }
103         allIconIds.insert(it.second.begin(), it.second.end());
104     }
105     if (allIconIds.size() == 0) {
106         cout << "Info: no icons need to scale, icon ids size is 0." << endl;
107         return true;
108     }
109     for (auto &id : allIconIds) {
110         std::map<int64_t, std::vector<ResourceItem>>::iterator iter = items_.find(id);
111         if (iter == items_.end()) {
112             continue;
113         }
114         for (auto &item : iter->second) {
115             if (!ScaleIcon(output, item)) {
116                 return false;
117             }
118         }
119     }
120     return true;
121 }
122 
ScaleIcon(const string & output,ResourceItem & item)123 bool FileManager::ScaleIcon(const string &output, ResourceItem &item)
124 {
125     std::string media = "media";
126     // item's data is short path for icon file, such as "entry/resources/base/media/app_icon.png"
127     const string currentData(reinterpret_cast<const char *>(item.GetData()), item.GetDataLength());
128     auto outIndex = currentData.find_last_of(SEPARATOR);
129     if (outIndex == string::npos) {
130         cerr << "Error: ScaleIcon invalid output name: " << currentData << endl;
131         return false;
132     }
133     // get current output file name and full path
134     string fileName = currentData.substr(outIndex + 1);
135     FileEntry::FilePath fullFilePath = FileEntry::FilePath(output).Append(RESOURCES_DIR).Append(item.GetLimitKey())
136         .Append(media).Append(fileName);
137     if (fullFilePath.GetExtension() == JSON_EXTENSION) {
138         cout << "Info: can't scale media json file." << endl;
139         return true;
140     }
141     const string fullOutPath = fullFilePath.GetPath();
142     // delete current output file
143     if (!ResourceUtil::RmoveFile(fullOutPath)) {
144         cout << "Error: ScaleIcon RmoveFile failed: " << fullOutPath << endl;
145         return false;
146     }
147     // get origin icon output full path with the origin icon file name in src
148     std::string dst = FileEntry::FilePath(output).Append(RESOURCES_DIR).Append(item.GetLimitKey()).Append(media)
149         .Append(item.GetName()).GetPath();
150     // the origin full file in src
151     std::string scaleDst = item.GetFilePath();
152     // scale icon
153     if (!CompressionParser::GetCompressionParser()->CheckAndScaleIcon(item.GetFilePath(), dst, scaleDst)) {
154         return false;
155     }
156     // compress scaled icon
157     if (!CompressionParser::GetCompressionParser()->CopyAndTranscode(scaleDst, dst)) {
158         return false;
159     }
160     string newFileName = FileEntry::FilePath(dst).GetFilename();
161     std::string newData = moduleName_ + SEPARATOR + RESOURCES_DIR + SEPARATOR + item.GetLimitKey() + SEPARATOR + media
162         + SEPARATOR + newFileName;
163     if (!item.SetData(reinterpret_cast<const int8_t *>(newData.c_str()), newData.length())) {
164         cerr << "Error: ScaleIcon resource item set data fail, data: " << newData << NEW_LINE_PATH
165              << item.GetFilePath() << endl;
166         return false;
167     }
168     return true;
169 }
170 }
171 }
172 }
173