• 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<cstdlib>
22 #include "file_entry.h"
23 
24 namespace OHOS {
25 namespace Global {
26 namespace Restool {
27 using namespace std;
28 const map<string, ResourceUtil::IgnoreType> ResourceUtil::IGNORE_FILE_REGEX = {
29     { "\\.git", IgnoreType::IGNORE_ALL },
30     { "\\.svn", IgnoreType::IGNORE_ALL },
31     { ".+\\.scc", IgnoreType::IGNORE_ALL },
32     { "\\.ds_store", IgnoreType::IGNORE_ALL },
33     { "desktop\\.ini", IgnoreType::IGNORE_ALL },
34     { "picasa\\.ini", IgnoreType::IGNORE_ALL },
35     { "\\..+", IgnoreType::IGNORE_ALL },
36     { "_.+", IgnoreType::IGNORE_DIR },
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::AdapateLongPath(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::AdapateLongPath(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::LAYOUT && type != ResType::PROF &&
140         type != ResType::ANIMATION && type != ResType::GRAPHIC) {
141         return name;
142     }
143 
144     string::size_type pos = name.find_last_of(".");
145     if (pos != string::npos) {
146         return name.substr(0, pos);
147     }
148     return name;
149 }
150 
ComposeStrings(const vector<string> & contents,bool addNull)151 string ResourceUtil::ComposeStrings(const vector<string> &contents, bool addNull)
152 {
153     string result;
154     for (const auto &iter : contents) {
155         if (iter.length() > UINT16_MAX) {
156             return "";
157         }
158 
159         uint16_t size = iter.length();
160         if (addNull) {
161             size += sizeof(char);
162         }
163         result.append(sizeof(char), (size & 0xff));
164         result.append(sizeof(char), (size >> 8));
165         result.append(iter);
166         result.append(sizeof(char), '\0');
167         if (result.length() > UINT16_MAX) {
168             return "";
169         }
170     }
171     return result;
172 }
173 
DecomposeStrings(const string & content)174 vector<string> ResourceUtil::DecomposeStrings(const string &content)
175 {
176     vector<string> result;
177     size_t length = content.length();
178     size_t pos = 0;
179     const size_t HEAD_LENGTH = 2;
180     while (pos < length) {
181         if (pos + HEAD_LENGTH >= length) {
182             result.clear();
183             return result;
184         }
185         uint16_t size = (content[pos] & 0xff) | ((content[pos + 1] & 0xff) << 8);
186         pos += HEAD_LENGTH;
187 
188         if (pos + size >= length) {
189             result.clear();
190             return result;
191         }
192         string buffer = content.substr(pos, size);
193         result.push_back(buffer);
194         pos += size + sizeof(char);
195     }
196     return result;
197 }
198 
GetResTypeFromString(const string & type)199 ResType ResourceUtil::GetResTypeFromString(const string &type)
200 {
201     ResType resType = GetResTypeByDir(type);
202     if (resType != ResType::INVALID_RES_TYPE) {
203         return resType;
204     }
205 
206     auto ret = g_contentClusterMap.find(type);
207     if (ret != g_contentClusterMap.end()) {
208         return ret->second;
209     }
210     return ResType::INVALID_RES_TYPE;
211 }
212 
CopyFleInner(const string & src,const string & dst)213 bool ResourceUtil::CopyFleInner(const string &src, const string &dst)
214 {
215     return FileEntry::CopyFileInner(src, dst);
216 }
217 
CreateDirs(const string & filePath)218 bool ResourceUtil::CreateDirs(const string &filePath)
219 {
220     if (FileExist(filePath)) {
221         return true;
222     }
223 
224     if (!FileEntry::CreateDirs(filePath)) {
225         cerr << "Error: create dir '" << filePath << "' failed, reason:" << strerror(errno) << endl;
226         return false;
227     }
228     return true;
229 }
230 
IsIgnoreFile(const string & filename,bool isFile)231 bool ResourceUtil::IsIgnoreFile(const string &filename, bool isFile)
232 {
233     string key = filename;
234     transform(key.begin(), key.end(), key.begin(), ::tolower);
235     for (const auto &iter : IGNORE_FILE_REGEX) {
236         if ((iter.second == IgnoreType::IGNORE_FILE && !isFile) ||
237             (iter.second == IgnoreType::IGNORE_DIR && isFile)) {
238             continue;
239         }
240         if (regex_match(key, regex(iter.first))) {
241             return true;
242         }
243     }
244     return false;
245 }
246 
NeedConverToSolidXml(ResType resType)247 bool ResourceUtil::NeedConverToSolidXml(ResType resType)
248 {
249     if (resType == ResType::LAYOUT || resType == ResType::ANIMATION ||
250         resType == ResType::GRAPHIC) {
251         return true;
252     }
253     return false;
254 }
255 
GenerateHash(const string & key)256 string ResourceUtil::GenerateHash(const string &key)
257 {
258     hash<string> hash_function;
259     return to_string(hash_function(key));
260 }
261 
RealPath(const string & path)262 string ResourceUtil::RealPath(const string &path)
263 {
264     return FileEntry::RealPath(path);
265 }
266 
IslegalPath(const string & path)267 bool ResourceUtil::IslegalPath(const string &path)
268 {
269     return path == "element" || path == "media" || path == "profile";
270 }
271 
StringReplace(string & sourceStr,const string & oldStr,const string & newStr)272 void ResourceUtil::StringReplace(string &sourceStr, const string &oldStr, const string &newStr)
273 {
274     string::size_type pos = 0;
275     string::size_type oldSize = oldStr.size();
276     string::size_type newSize = newStr.size();
277     while ((pos = sourceStr.find(oldStr, pos)) != string::npos) {
278         sourceStr.replace(pos, oldSize, newStr.c_str());
279         pos += newSize;
280     }
281 }
282 
GetLocaleLimitkey(const KeyParam & KeyParam)283 string ResourceUtil::GetLocaleLimitkey(const KeyParam &KeyParam)
284 {
285     string str(reinterpret_cast<const char *>(&KeyParam.value));
286     reverse(str.begin(), str.end());
287     return str;
288 }
289 
GetDeviceTypeLimitkey(const KeyParam & KeyParam)290 string ResourceUtil::GetDeviceTypeLimitkey(const KeyParam &KeyParam)
291 {
292     auto ret = find_if(g_deviceMap.begin(), g_deviceMap.end(), [KeyParam](const auto &iter) {
293         return KeyParam.value == static_cast<const uint32_t>(iter.second);
294     });
295     if (ret == g_deviceMap.end()) {
296         return string();
297     }
298     return ret->first;
299 }
300 
GetResolutionLimitkey(const KeyParam & KeyParam)301 string ResourceUtil::GetResolutionLimitkey(const KeyParam &KeyParam)
302 {
303     auto ret = find_if(g_resolutionMap.begin(), g_resolutionMap.end(), [KeyParam](const auto &iter) {
304         return KeyParam.value == static_cast<const uint32_t>(iter.second);
305     });
306     if (ret == g_resolutionMap.end()) {
307         return string();
308     }
309     return ret->first;
310 }
311 
GetKeyParamValue(const KeyParam & KeyParam)312 string ResourceUtil::GetKeyParamValue(const KeyParam &KeyParam)
313 {
314     string val;
315     switch (KeyParam.keyType) {
316         case KeyType::ORIENTATION:
317             val = KeyParam.value == static_cast<const uint32_t>(OrientationType::VERTICAL) ? "vertical" : "horizontal";
318             break;
319         case KeyType::NIGHTMODE:
320             val = KeyParam.value == static_cast<const uint32_t>(NightMode::DARK) ? "dark" : "light";
321             break;
322         case KeyType::DEVICETYPE:
323             val = GetDeviceTypeLimitkey(KeyParam);
324             break;
325         case KeyType::RESOLUTION:
326             val = GetResolutionLimitkey(KeyParam);
327             break;
328         case KeyType::LANGUAGE:
329         case KeyType::REGION:
330             val = GetLocaleLimitkey(KeyParam);
331             break;
332         default:
333             val = to_string(KeyParam.value);
334             break;
335     }
336     return val;
337 }
338 
PaserKeyParam(const vector<KeyParam> & keyParams)339 string ResourceUtil::PaserKeyParam(const vector<KeyParam> &keyParams)
340 {
341     if (keyParams.size() == 0) {
342         return "base";
343     }
344     string result;
345     for (const auto &keyparam : keyParams) {
346         string limitKey = GetKeyParamValue(keyparam);
347         if (limitKey.empty()) {
348             continue;
349         }
350         if (keyparam.keyType == KeyType::MCC) {
351             limitKey = "mcc" + limitKey;
352         }
353         if (keyparam.keyType == KeyType::MNC) {
354             limitKey = "mnc" + limitKey;
355         }
356         if (keyparam.keyType == KeyType::REGION || keyparam.keyType == KeyType::MNC) {
357             result = result + "_" + limitKey;
358         } else {
359             result = result + "-" + limitKey;
360         }
361     }
362     if (!result.empty()) {
363         result = result.substr(1);
364     }
365     return result;
366 }
367 
368 }
369 }
370 }
371