• 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_util.h"
17 #include<algorithm>
18 #include<fstream>
19 #include<iostream>
20 #include<regex>
21 #include "file_entry.h"
22 #ifdef __WIN32
23 #include "windows.h"
24 #endif
25 
26 namespace OHOS {
27 namespace Global {
28 namespace Restool {
29 using namespace std;
30 const map<string, ResourceUtil::IgnoreType> ResourceUtil::IGNORE_FILE_REGEX = {
31     { "\\.git", IgnoreType::IGNORE_ALL },
32     { "\\.svn", IgnoreType::IGNORE_ALL },
33     { ".+\\.scc", IgnoreType::IGNORE_ALL },
34     { "\\.ds_store", IgnoreType::IGNORE_ALL },
35     { "desktop\\.ini", IgnoreType::IGNORE_ALL },
36     { "picasa\\.ini", IgnoreType::IGNORE_ALL },
37     { "\\..+", IgnoreType::IGNORE_ALL },
38     { "_.+", IgnoreType::IGNORE_DIR },
39     { "cvs", IgnoreType::IGNORE_ALL },
40     { "thumbs\\.db", IgnoreType::IGNORE_ALL },
41     { ".+~", IgnoreType::IGNORE_ALL }
42 };
43 
Split(const string & str,vector<string> & out,const string & splitter)44 void ResourceUtil::Split(const string &str, vector<string> &out, const string &splitter)
45 {
46     string::size_type len = str.size();
47     string::size_type begin = 0;
48     string::size_type end = str.find(splitter, begin);
49     while (end != string::npos) {
50         string sub = str.substr(begin, end - begin);
51         out.push_back(sub);
52         begin = end + splitter.size();
53         if (begin >= len) {
54             break;
55         }
56         end = str.find(splitter, begin);
57     }
58 
59     if (begin < len) {
60         out.push_back(str.substr(begin));
61     }
62 }
63 
FileExist(const string & path)64 bool ResourceUtil::FileExist(const string &path)
65 {
66     return FileEntry::Exist(path);
67 }
68 
RmoveAllDir(const string & path)69 bool ResourceUtil::RmoveAllDir(const string &path)
70 {
71     return FileEntry::RemoveAllDir(path);
72 }
73 
OpenJsonFile(const string & path,Json::Value & root)74 bool ResourceUtil::OpenJsonFile(const string &path, Json::Value &root)
75 {
76     ifstream ifs(path, ios::binary);
77     if (!ifs) {
78         cerr << "Error: open json failed '" << path << "'" << endl;
79         return false;
80     }
81 
82     Json::CharReaderBuilder readBuilder;
83     readBuilder["collectComments"] = false;
84     readBuilder["failIfExtra"] = true;
85     JSONCPP_STRING errs;
86     if (!parseFromStream(readBuilder, ifs, &root, &errs)) {
87         cerr << "Error: parseFromStream '" << path;
88         cerr << "\n" << errs << endl;
89         ifs.close();
90         return false;
91     }
92     ifs.close();
93     return true;
94 }
95 
SaveToJsonFile(const string & path,const Json::Value & root)96 bool ResourceUtil::SaveToJsonFile(const string &path, const Json::Value &root)
97 {
98     Json::StreamWriterBuilder writerBuilder;
99     writerBuilder["indentation"] = "    ";
100     writerBuilder["emitUTF8"] = true;
101     unique_ptr<Json::StreamWriter> writer(writerBuilder.newStreamWriter());
102     ofstream out(path, ofstream::out | ofstream::binary);
103     if (!out.is_open()) {
104         cerr << "Error: open fail " << path << endl;
105         return false;
106     }
107     writer->write(root, &out);
108     out.close();
109     return true;
110 }
111 
GetResTypeByDir(const string & name)112 ResType ResourceUtil::GetResTypeByDir(const string &name)
113 {
114     auto ret = g_fileClusterMap.find(name);
115     if (ret == g_fileClusterMap.end()) {
116         return ResType::INVALID_RES_TYPE;
117     }
118     return ret->second;
119 }
120 
ResTypeToString(ResType type)121 string ResourceUtil::ResTypeToString(ResType type)
122 {
123     auto ret = find_if(g_fileClusterMap.begin(), g_fileClusterMap.end(), [type](auto iter) {
124         return iter.second == type;
125     });
126     if (ret != g_fileClusterMap.end()) {
127         return ret->first;
128     }
129 
130     ret = find_if(g_contentClusterMap.begin(), g_contentClusterMap.end(), [type](auto iter) {
131         return iter.second == type;
132     });
133     if (ret != g_contentClusterMap.end()) {
134         return ret->first;
135     }
136     return "";
137 }
138 
GetIdName(const string & name,ResType type)139 string ResourceUtil::GetIdName(const string &name, ResType type)
140 {
141     if (type != ResType::MEDIA && type != ResType::LAYOUT && type != ResType::PROF &&
142         type != ResType::ANIMATION && type != ResType::GRAPHIC) {
143         return name;
144     }
145 
146     string::size_type pos = name.find_last_of(".");
147     if (pos != string::npos) {
148         return name.substr(0, pos);
149     }
150     return name;
151 }
152 
ComposeStrings(const vector<string> & contents,bool addNull)153 string ResourceUtil::ComposeStrings(const vector<string> &contents, bool addNull)
154 {
155     string result;
156     for (const auto &iter : contents) {
157         if (iter.length() > UINT16_MAX) {
158             return "";
159         }
160 
161         uint16_t size = iter.length();
162         if (addNull) {
163             size += sizeof(char);
164         }
165         result.append(sizeof(char), (size & 0xff));
166         result.append(sizeof(char), (size >> 8));
167         result.append(iter);
168         result.append(sizeof(char), '\0');
169         if (result.length() > UINT16_MAX) {
170             return "";
171         }
172     }
173     return result;
174 }
175 
DecomposeStrings(const string & content)176 vector<string> ResourceUtil::DecomposeStrings(const string &content)
177 {
178     vector<string> result;
179     size_t length = content.length();
180     size_t pos = 0;
181     const size_t HEAD_LENGTH = 2;
182     while (pos < length) {
183         if (pos + HEAD_LENGTH >= length) {
184             result.clear();
185             return result;
186         }
187         uint16_t size = (content[pos] & 0xff) | ((content[pos + 1] & 0xff) << 8);
188         pos += HEAD_LENGTH;
189 
190         if (pos + size >= length) {
191             result.clear();
192             return result;
193         }
194         string buffer = content.substr(pos, size);
195         result.push_back(buffer);
196         pos += size + sizeof(char);
197     }
198     return result;
199 }
200 
GetResTypeFromString(const string & type)201 ResType ResourceUtil::GetResTypeFromString(const string &type)
202 {
203     ResType resType = GetResTypeByDir(type);
204     if (resType != ResType::INVALID_RES_TYPE) {
205         return resType;
206     }
207 
208     auto ret = g_contentClusterMap.find(type);
209     if (ret != g_contentClusterMap.end()) {
210         return ret->second;
211     }
212     return ResType::INVALID_RES_TYPE;
213 }
214 
CopyFleInner(const string & src,const string & dst)215 bool ResourceUtil::CopyFleInner(const string &src, const string &dst)
216 {
217 #ifdef __WIN32
218     if (!CopyFileA(src.c_str(), dst.c_str(), false)) {
219         cerr << "Error: copy file fail from '" << src << "' to '" << dst << "'" << endl;
220         return false;
221     }
222 #else
223     if (!FileEntry::CopyFile(src, dst)) {
224         cerr << "Error: copy file fail from '" << src << "' to '" << dst << "'" << endl;
225         return false;
226     }
227 #endif
228     return true;
229 }
230 
CreateDirs(const string & filePath)231 bool ResourceUtil::CreateDirs(const string &filePath)
232 {
233     if (FileExist(filePath)) {
234         return true;
235     }
236 
237     if (!FileEntry::CreateDirs(filePath)) {
238         cerr << "Error: create dir fail '" << filePath << "'" << endl;
239         return false;
240     }
241     return true;
242 }
243 
IsIgnoreFile(const string & filename,bool isFile)244 bool ResourceUtil::IsIgnoreFile(const string &filename, bool isFile)
245 {
246     string key = filename;
247     transform(key.begin(), key.end(), key.begin(), ::tolower);
248     for (const auto &iter : IGNORE_FILE_REGEX) {
249         if ((iter.second == IgnoreType::IGNORE_FILE && !isFile) ||
250             (iter.second == IgnoreType::IGNORE_DIR && isFile)) {
251             continue;
252         }
253         if (regex_match(key, regex(iter.first))) {
254             return true;
255         }
256     }
257     return false;
258 }
259 
NeedConverToSolidXml(ResType resType)260 bool ResourceUtil::NeedConverToSolidXml(ResType resType)
261 {
262     if (resType == ResType::LAYOUT || resType == ResType::ANIMATION ||
263         resType == ResType::GRAPHIC) {
264         return true;
265     }
266     return false;
267 }
268 
GenerateHash(const std::string key)269 string ResourceUtil::GenerateHash(const std::string key)
270 {
271     hash<string> hash_function;
272     return to_string(hash_function(key));
273 }
274 
StringReplace(string & sourceStr,const string & oldStr,const string & newStr)275 void ResourceUtil::StringReplace(string &sourceStr, const string &oldStr, const string &newStr)
276 {
277     string::size_type pos = 0;
278     string::size_type oldSize = oldStr.size();
279     string::size_type newSize = newStr.size();
280     while ((pos = sourceStr.find(oldStr, pos)) != string::npos) {
281         sourceStr.replace(pos, oldSize, newStr.c_str());
282         pos += newSize;
283     }
284 }
285 
GetLocaleLimitkey(const KeyParam & KeyParam)286 string ResourceUtil::GetLocaleLimitkey(const KeyParam &KeyParam)
287 {
288     string str(reinterpret_cast<const char *>(&KeyParam.value));
289     reverse(str.begin(), str.end());
290     return str;
291 }
292 
GetDeviceTypeLimitkey(const KeyParam & KeyParam)293 string ResourceUtil::GetDeviceTypeLimitkey(const KeyParam &KeyParam)
294 {
295     auto ret = find_if(g_deviceMap.begin(), g_deviceMap.end(), [KeyParam](const auto &iter) {
296         return KeyParam.value == static_cast<const int32_t>(iter.second);
297     });
298     if (ret == g_deviceMap.end()) {
299         return string();
300     }
301     return ret->first;
302 }
303 
GetResolutionLimitkey(const KeyParam & KeyParam)304 string ResourceUtil::GetResolutionLimitkey(const KeyParam &KeyParam)
305 {
306     auto ret = find_if(g_resolutionMap.begin(), g_resolutionMap.end(), [KeyParam](const auto &iter) {
307         return KeyParam.value == static_cast<const int32_t>(iter.second);
308     });
309     if (ret == g_resolutionMap.end()) {
310         return string();
311     }
312     return ret->first;
313 }
314 
GetKeyParamValue(const KeyParam & KeyParam)315 string ResourceUtil::GetKeyParamValue(const KeyParam &KeyParam)
316 {
317     string val;
318     switch (KeyParam.keyType) {
319         case KeyType::ORIENTATION:
320             val = KeyParam.value == static_cast<const int32_t>(OrientationType::VERTICAL) ? "vertical" : "horizontal";
321             break;
322         case KeyType::NIGHTMODE:
323             val = KeyParam.value == static_cast<const int32_t>(NightMode::DARK) ? "dark" : "light";
324             break;
325         case KeyType::DEVICETYPE:
326             val = GetDeviceTypeLimitkey(KeyParam);
327             break;
328         case KeyType::RESOLUTION:
329             val = GetResolutionLimitkey(KeyParam);
330             break;
331         case KeyType::LANGUAGE:
332         case KeyType::REGION:
333             val = GetLocaleLimitkey(KeyParam);
334             break;
335         default:
336             val = to_string(KeyParam.value);
337             break;
338     }
339     return val;
340 }
341 
PaserKeyParam(const vector<KeyParam> & keyParams)342 string ResourceUtil::PaserKeyParam(const vector<KeyParam> &keyParams)
343 {
344     if (keyParams.size() == 0) {
345         return "base";
346     }
347     string result;
348     for (const auto &keyparam : keyParams) {
349         string limitKey = GetKeyParamValue(keyparam);
350         if (limitKey.empty()) {
351             continue;
352         }
353         if (keyparam.keyType == KeyType::MCC) {
354             limitKey = "mcc" + limitKey;
355         }
356         if (keyparam.keyType == KeyType::MNC) {
357             limitKey = "mnc" + limitKey;
358         }
359         if (keyparam.keyType == KeyType::REGION || keyparam.keyType == KeyType::MNC) {
360             result = result + "_" + limitKey;
361         } else {
362             result = result + "-" + limitKey;
363         }
364     }
365     if (!result.empty()) {
366         result = result.substr(1);
367     }
368     return result;
369 }
370 
371 }
372 }
373 }
374