• 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 <cstdlib>
19 #include <fstream>
20 #include <iostream>
21 #include <iomanip>
22 #include <regex>
23 #include "file_entry.h"
24 
25 namespace OHOS {
26 namespace Global {
27 namespace Restool {
28 using namespace std;
29 const map<string, ResourceUtil::IgnoreType> ResourceUtil::IGNORE_FILE_REGEX = {
30     { "\\.git", IgnoreType::IGNORE_ALL },
31     { "\\.svn", IgnoreType::IGNORE_ALL },
32     { ".+\\.scc", IgnoreType::IGNORE_ALL },
33     { "\\.ds_store", IgnoreType::IGNORE_ALL },
34     { "desktop\\.ini", IgnoreType::IGNORE_ALL },
35     { "picasa\\.ini", IgnoreType::IGNORE_ALL },
36     { "\\..+", IgnoreType::IGNORE_ALL },
37     { "cvs", IgnoreType::IGNORE_ALL },
38     { "thumbs\\.db", IgnoreType::IGNORE_ALL },
39     { ".+~", IgnoreType::IGNORE_ALL }
40 };
41 
Split(const string & str,vector<string> & out,const string & splitter)42 void ResourceUtil::Split(const string &str, vector<string> &out, const string &splitter)
43 {
44     string::size_type len = str.size();
45     string::size_type begin = 0;
46     string::size_type end = str.find(splitter, begin);
47     while (end != string::npos) {
48         string sub = str.substr(begin, end - begin);
49         out.push_back(sub);
50         begin = end + splitter.size();
51         if (begin >= len) {
52             break;
53         }
54         end = str.find(splitter, begin);
55     }
56 
57     if (begin < len) {
58         out.push_back(str.substr(begin));
59     }
60 }
61 
FileExist(const string & path)62 bool ResourceUtil::FileExist(const string &path)
63 {
64     return FileEntry::Exist(path);
65 }
66 
RmoveAllDir(const string & path)67 bool ResourceUtil::RmoveAllDir(const string &path)
68 {
69     return FileEntry::RemoveAllDir(path);
70 }
71 
OpenJsonFile(const string & path,Json::Value & root)72 bool ResourceUtil::OpenJsonFile(const string &path, Json::Value &root)
73 {
74     ifstream ifs(FileEntry::AdaptLongPath(path), ios::binary);
75     if (!ifs.is_open()) {
76         cerr << "Error: open json failed '" << path << "', reason: " << strerror(errno) << endl;
77         return false;
78     }
79 
80     Json::CharReaderBuilder readBuilder;
81     readBuilder["collectComments"] = false;
82     readBuilder["failIfExtra"] = true;
83     JSONCPP_STRING errs;
84     if (!parseFromStream(readBuilder, ifs, &root, &errs)) {
85         cerr << "Error: parseFromStream failed." << NEW_LINE_PATH << path;
86         cerr << "\n" << errs << endl;
87         ifs.close();
88         return false;
89     }
90     ifs.close();
91     return true;
92 }
93 
SaveToJsonFile(const string & path,const Json::Value & root)94 bool ResourceUtil::SaveToJsonFile(const string &path, const Json::Value &root)
95 {
96     Json::StreamWriterBuilder writerBuilder;
97     writerBuilder["indentation"] = "    ";
98     writerBuilder["emitUTF8"] = true;
99     unique_ptr<Json::StreamWriter> writer(writerBuilder.newStreamWriter());
100     ofstream out(FileEntry::AdaptLongPath(path), ofstream::out | ofstream::binary);
101     if (!out.is_open()) {
102         cerr << "Error: open failed '" << path <<"', reason: " << strerror(errno) << endl;
103         return false;
104     }
105     writer->write(root, &out);
106     out.close();
107     return true;
108 }
109 
GetResTypeByDir(const string & name)110 ResType ResourceUtil::GetResTypeByDir(const string &name)
111 {
112     auto ret = g_fileClusterMap.find(name);
113     if (ret == g_fileClusterMap.end()) {
114         return ResType::INVALID_RES_TYPE;
115     }
116     return ret->second;
117 }
118 
ResTypeToString(ResType type)119 string ResourceUtil::ResTypeToString(ResType type)
120 {
121     auto ret = find_if(g_fileClusterMap.begin(), g_fileClusterMap.end(), [type](auto iter) {
122         return iter.second == type;
123     });
124     if (ret != g_fileClusterMap.end()) {
125         return ret->first;
126     }
127 
128     ret = find_if(g_contentClusterMap.begin(), g_contentClusterMap.end(), [type](auto iter) {
129         return iter.second == type;
130     });
131     if (ret != g_contentClusterMap.end()) {
132         return ret->first;
133     }
134     return "";
135 }
136 
GetIdName(const string & name,ResType type)137 string ResourceUtil::GetIdName(const string &name, ResType type)
138 {
139     if (type != ResType::MEDIA && type != ResType::PROF) {
140         return name;
141     }
142 
143     string::size_type pos = name.find_last_of(".");
144     if (pos != string::npos) {
145         return name.substr(0, pos);
146     }
147     return name;
148 }
149 
ComposeStrings(const vector<string> & contents,bool addNull)150 string ResourceUtil::ComposeStrings(const vector<string> &contents, bool addNull)
151 {
152     string result;
153     for (const auto &iter : contents) {
154         if (iter.length() > UINT16_MAX) {
155             return "";
156         }
157 
158         uint16_t size = iter.length();
159         if (addNull) {
160             size += sizeof(char);
161         }
162         result.append(sizeof(char), (size & 0xff));
163         result.append(sizeof(char), (size >> 8)); // Move 8 bits to the right
164         result.append(iter);
165         result.append(sizeof(char), '\0');
166         if (result.length() > UINT16_MAX) {
167             return "";
168         }
169     }
170     return result;
171 }
172 
DecomposeStrings(const string & content)173 vector<string> ResourceUtil::DecomposeStrings(const string &content)
174 {
175     vector<string> result;
176     size_t length = content.length();
177     size_t pos = 0;
178     const size_t HEAD_LENGTH = 2;
179     while (pos < length) {
180         if (pos + HEAD_LENGTH >= length) {
181             result.clear();
182             return result;
183         }
184         uint16_t size = (content[pos] & 0xff) | ((content[pos + 1] & 0xff) << 8);
185         pos += HEAD_LENGTH;
186 
187         if (pos + size >= length) {
188             result.clear();
189             return result;
190         }
191         string buffer = content.substr(pos, size);
192         result.push_back(buffer);
193         pos += size + sizeof(char);
194     }
195     return result;
196 }
197 
GetResTypeFromString(const string & type)198 ResType ResourceUtil::GetResTypeFromString(const string &type)
199 {
200     ResType resType = GetResTypeByDir(type);
201     if (resType != ResType::INVALID_RES_TYPE) {
202         return resType;
203     }
204 
205     auto ret = g_contentClusterMap.find(type);
206     if (ret != g_contentClusterMap.end()) {
207         return ret->second;
208     }
209     return ResType::INVALID_RES_TYPE;
210 }
211 
CopyFleInner(const string & src,const string & dst)212 bool ResourceUtil::CopyFleInner(const string &src, const string &dst)
213 {
214     return FileEntry::CopyFileInner(src, dst);
215 }
216 
CreateDirs(const string & filePath)217 bool ResourceUtil::CreateDirs(const string &filePath)
218 {
219     if (FileExist(filePath)) {
220         return true;
221     }
222 
223     if (!FileEntry::CreateDirs(filePath)) {
224         cerr << "Error: create dir '" << filePath << "' failed, reason:" << strerror(errno) << endl;
225         return false;
226     }
227     return true;
228 }
229 
IsIgnoreFile(const string & filename,bool isFile)230 bool ResourceUtil::IsIgnoreFile(const string &filename, bool isFile)
231 {
232     string key = filename;
233     transform(key.begin(), key.end(), key.begin(), ::tolower);
234     for (const auto &iter : IGNORE_FILE_REGEX) {
235         if ((iter.second == IgnoreType::IGNORE_FILE && !isFile) ||
236             (iter.second == IgnoreType::IGNORE_DIR && isFile)) {
237             continue;
238         }
239         if (regex_match(key, regex(iter.first))) {
240             return true;
241         }
242     }
243     return false;
244 }
245 
GenerateHash(const string & key)246 string ResourceUtil::GenerateHash(const string &key)
247 {
248     hash<string> hash_function;
249     return to_string(hash_function(key));
250 }
251 
RealPath(const string & path)252 string ResourceUtil::RealPath(const string &path)
253 {
254     return FileEntry::RealPath(path);
255 }
256 
IslegalPath(const string & path)257 bool ResourceUtil::IslegalPath(const string &path)
258 {
259     return path == "element" || path == "media" || path == "profile";
260 }
261 
StringReplace(string & sourceStr,const string & oldStr,const string & newStr)262 void ResourceUtil::StringReplace(string &sourceStr, const string &oldStr, const string &newStr)
263 {
264     string::size_type pos = 0;
265     string::size_type oldSize = oldStr.size();
266     string::size_type newSize = newStr.size();
267     while ((pos = sourceStr.find(oldStr, pos)) != string::npos) {
268         sourceStr.replace(pos, oldSize, newStr.c_str());
269         pos += newSize;
270     }
271 }
272 
GetLocaleLimitkey(const KeyParam & KeyParam)273 string ResourceUtil::GetLocaleLimitkey(const KeyParam &KeyParam)
274 {
275     string str(reinterpret_cast<const char *>(&KeyParam.value));
276     reverse(str.begin(), str.end());
277     return str;
278 }
279 
GetDeviceTypeLimitkey(const KeyParam & KeyParam)280 string ResourceUtil::GetDeviceTypeLimitkey(const KeyParam &KeyParam)
281 {
282     auto ret = find_if(g_deviceMap.begin(), g_deviceMap.end(), [KeyParam](const auto &iter) {
283         return KeyParam.value == static_cast<const uint32_t>(iter.second);
284     });
285     if (ret == g_deviceMap.end()) {
286         return string();
287     }
288     return ret->first;
289 }
290 
GetResolutionLimitkey(const KeyParam & KeyParam)291 string ResourceUtil::GetResolutionLimitkey(const KeyParam &KeyParam)
292 {
293     auto ret = find_if(g_resolutionMap.begin(), g_resolutionMap.end(), [KeyParam](const auto &iter) {
294         return KeyParam.value == static_cast<const uint32_t>(iter.second);
295     });
296     if (ret == g_resolutionMap.end()) {
297         return string();
298     }
299     return ret->first;
300 }
301 
GetKeyParamValue(const KeyParam & KeyParam)302 string ResourceUtil::GetKeyParamValue(const KeyParam &KeyParam)
303 {
304     string val;
305     switch (KeyParam.keyType) {
306         case KeyType::ORIENTATION:
307             val = KeyParam.value == static_cast<const uint32_t>(OrientationType::VERTICAL) ? "vertical" : "horizontal";
308             break;
309         case KeyType::NIGHTMODE:
310             val = KeyParam.value == static_cast<const uint32_t>(NightMode::DARK) ? "dark" : "light";
311             break;
312         case KeyType::DEVICETYPE:
313             val = GetDeviceTypeLimitkey(KeyParam);
314             break;
315         case KeyType::RESOLUTION:
316             val = GetResolutionLimitkey(KeyParam);
317             break;
318         case KeyType::LANGUAGE:
319         case KeyType::REGION:
320             val = GetLocaleLimitkey(KeyParam);
321             break;
322         default:
323             val = to_string(KeyParam.value);
324             break;
325     }
326     return val;
327 }
328 
PaserKeyParam(const vector<KeyParam> & keyParams)329 string ResourceUtil::PaserKeyParam(const vector<KeyParam> &keyParams)
330 {
331     if (keyParams.size() == 0) {
332         return "base";
333     }
334     string result;
335     for (const auto &keyparam : keyParams) {
336         string limitKey = GetKeyParamValue(keyparam);
337         if (limitKey.empty()) {
338             continue;
339         }
340         if (keyparam.keyType == KeyType::MCC) {
341             limitKey = "mcc" + limitKey;
342         }
343         if (keyparam.keyType == KeyType::MNC) {
344             limitKey = "mnc" + limitKey;
345         }
346         if (keyparam.keyType == KeyType::REGION || keyparam.keyType == KeyType::MNC) {
347             result = result + "_" + limitKey;
348         } else {
349             result = result + "-" + limitKey;
350         }
351     }
352     if (!result.empty()) {
353         result = result.substr(1);
354     }
355     return result;
356 }
357 
DecToHexStr(const int32_t i)358 string ResourceUtil::DecToHexStr(const int32_t i)
359 {
360     stringstream ot;
361     string result;
362     ot << setiosflags(ios::uppercase) << "0x" << hex << setw(8) << setfill('0') << i; // 0x expadding 8 bit
363     ot >> result;
364     return result;
365 }
366 
CheckHexStr(const string & hex)367 bool ResourceUtil::CheckHexStr(const string &hex)
368 {
369     if (regex_match(hex, regex("^0[xX][0-9a-fA-F]{8}"))) {
370         return true;
371     }
372     return false;
373 }
374 
GetAllRestypeString()375 string ResourceUtil::GetAllRestypeString()
376 {
377     string result;
378     for (auto iter = g_contentClusterMap.begin(); iter != g_contentClusterMap.end(); ++iter) {
379         result = result + "," + iter->first;
380     }
381     return result;
382 }
383 
GetBaseElementPath(const string input)384 FileEntry::FilePath ResourceUtil::GetBaseElementPath(const string input)
385 {
386     return FileEntry::FilePath(input).Append("base").Append("element");
387 }
388 
GetMainPath(const string input)389 FileEntry::FilePath ResourceUtil::GetMainPath(const string input)
390 {
391     return FileEntry::FilePath(input).GetParent();
392 }
393 
GetNormalSize(const vector<KeyParam> & keyParams,uint32_t index)394 uint32_t ResourceUtil::GetNormalSize(const vector<KeyParam> &keyParams, uint32_t index)
395 {
396     string device;
397     string dpi;
398     if (keyParams.size() == 0) {
399         device = "phone";
400         dpi = "sdpi";
401     }
402     for (const auto &keyparam : keyParams) {
403         string limitKey = GetKeyParamValue(keyparam);
404         if (limitKey.empty()) {
405             continue;
406         }
407         if (keyparam.keyType == KeyType::DEVICETYPE) {
408             device = limitKey;
409         } else if (keyparam.keyType == KeyType::RESOLUTION) {
410             dpi = limitKey;
411         }
412     }
413     if (device.empty()) {
414         device = "phone";
415     }
416     if (dpi.empty()) {
417         dpi = "sdpi";
418     }
419     if (device != "phone" && device != "tablet") {
420         return 0;
421     }
422     return g_normalIconMap.find(dpi + "-" + device)->second[index];
423 }
424 
isUnicodeInPlane15or16(int unicode)425 bool ResourceUtil::isUnicodeInPlane15or16(int unicode)
426 {
427     return (unicode >= 0xF0000 && unicode <= 0xFFFFF) || (unicode >= 0x100000 && unicode <= 0x10FFFF);
428 }
429 
RemoveSpaces(string & str)430 void ResourceUtil::RemoveSpaces(string &str)
431 {
432     str.erase(0, str.find_first_not_of(" "));
433     str.erase(str.find_last_not_of(" ") + 1); // move back one place
434 }
435 
436 }
437 }
438 }
439