1 /*
2 * Copyright (c) 2021-2022 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 #include "utils/utils.h"
16
17 #include <cstdlib>
18 #include <cerrno>
19 #include <climits>
20 #include <fstream>
21 #include <vector>
22 #include <sys/stat.h>
23 #include "hilog_wrapper.h"
24 #ifdef __LINUX__
25 #include <cstring>
26 #endif
27
28 #if !defined(__WINNT__) && !defined(__IDE_PREVIEW__) && !defined(__ARKUI_CROSS__)
29 #include "hitrace_meter.h"
30 #include "parameters.h"
31 #endif
32
33 #ifdef __WINNT__
34 #include <shlwapi.h>
35 #include <windows.h>
36 #include <io.h>
37 #undef ERROR
38 #endif
39
40 namespace OHOS {
41 namespace Global {
42 namespace Resource {
43 constexpr int ERROR_RESULT = -1;
44 constexpr int CONVERT_BASE = 10;
45
46 const std::set<std::string> Utils::tailSet {
47 ".hap",
48 ".hsp",
49 };
50
51 std::vector<char> g_codes = {
52 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M',
53 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z',
54 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm',
55 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z',
56 '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '+', '/'
57 };
58
GetMediaBase64Data(const std::string & iconPath,std::string & base64Data)59 RState Utils::GetMediaBase64Data(const std::string& iconPath, std::string &base64Data)
60 {
61 size_t len = 0;
62 auto tempData = Utils::LoadResourceFile(iconPath, len);
63 if (tempData == nullptr) {
64 RESMGR_HILOGE(RESMGR_TAG, "get the tempData error");
65 return NOT_FOUND;
66 }
67 auto pos = iconPath.find_last_of('.');
68 std::string imgType;
69 if (pos != std::string::npos) {
70 imgType = iconPath.substr(pos + 1);
71 }
72 Utils::EncodeBase64(tempData, len, imgType, base64Data);
73 return SUCCESS;
74 }
75
LoadResourceFile(const std::string & path,size_t & len)76 std::unique_ptr<uint8_t[]> Utils::LoadResourceFile(const std::string &path, size_t &len)
77 {
78 std::ifstream mediaStream(path, std::ios::binary);
79 if (!mediaStream.is_open()) {
80 return nullptr;
81 }
82 mediaStream.seekg(0, std::ios::end);
83 int length = mediaStream.tellg();
84 if (length == ERROR_RESULT) {
85 RESMGR_HILOGE(RESMGR_TAG, "failed to get the file length");
86 mediaStream.close();
87 return nullptr;
88 } else {
89 len = static_cast<size_t>(length);
90 }
91 std::unique_ptr<uint8_t[]> tempData = std::make_unique<uint8_t[]>(len);
92 if (tempData == nullptr) {
93 mediaStream.close();
94 return nullptr;
95 }
96 mediaStream.seekg(0, std::ios::beg);
97 mediaStream.read(reinterpret_cast<char *>(tempData.get()), len);
98 mediaStream.close();
99 return tempData;
100 }
101
EncodeBase64(std::unique_ptr<uint8_t[]> & data,int srcLen,const std::string & imgType,std::string & dstData)102 RState Utils::EncodeBase64(std::unique_ptr<uint8_t[]> &data, int srcLen,
103 const std::string &imgType, std::string &dstData)
104 {
105 const unsigned char *srcData = data.get();
106 if (srcData == nullptr) {
107 return ERROR;
108 }
109 std::string base64data;
110 base64data += "data:image/" + imgType + ";base64,";
111 int i = 0;
112 // encode in groups of every 3 bytes
113 for (; i <= srcLen - 3; i += 3) {
114 unsigned char byte1 = static_cast<unsigned char>(srcData[i]);
115 unsigned char byte2 = static_cast<unsigned char>(srcData[i + 1]);
116 unsigned char byte3 = static_cast<unsigned char>(srcData[i + 2]);
117 base64data += g_codes[byte1 >> BitOperatorNum::BIT_TWO];
118 base64data += g_codes[((byte1 & 0x3) << BitOperatorNum::BIT_FOUR) | (byte2 >> BitOperatorNum::BIT_FOUR)];
119 base64data += g_codes[((byte2 & 0xF) << BitOperatorNum::BIT_TWO) | (byte3 >> BitOperatorNum::BIT_SIX)];
120 base64data += g_codes[byte3 & 0x3F];
121 }
122
123 if (i >= srcLen) {
124 dstData = base64data;
125 return SUCCESS;
126 }
127
128 // Handle the case where there is one element left
129 if (srcLen % ArrayLen::LEN_THREE == 1) {
130 unsigned char byte1 = static_cast<unsigned char>(srcData[i]);
131 base64data += g_codes[byte1 >> BitOperatorNum::BIT_TWO];
132 base64data += g_codes[(byte1 & 0x3) << BitOperatorNum::BIT_FOUR];
133 base64data += '=';
134 base64data += '=';
135 } else if (srcLen % ArrayLen::LEN_THREE == ArrayIndex::INDEX_TWO) {
136 unsigned char byte1 = static_cast<unsigned char>(srcData[i]);
137 unsigned char byte2 = static_cast<unsigned char>(srcData[i + 1]);
138 base64data += g_codes[byte1 >> BitOperatorNum::BIT_TWO];
139 base64data += g_codes[((byte1 & 0x3) << BitOperatorNum::BIT_FOUR) | (byte2 >> BitOperatorNum::BIT_FOUR)];
140 base64data += g_codes[(byte2 & 0xF) << BitOperatorNum::BIT_TWO];
141 base64data += '=';
142 }
143 dstData = base64data;
144 return SUCCESS;
145 }
146
IsAlphaString(const char * s,int32_t len)147 bool Utils::IsAlphaString(const char *s, int32_t len)
148 {
149 if (s == nullptr) {
150 return false;
151 }
152 int32_t i;
153 for (i = 0; i < len; i++) {
154 char c = *(s + i);
155 if (!((c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z'))) {
156 return false;
157 }
158 }
159 return true;
160 }
161
IsNumericString(const char * s,int32_t len)162 bool Utils::IsNumericString(const char *s, int32_t len)
163 {
164 if (s == nullptr) {
165 return false;
166 }
167 int32_t i;
168 for (i = 0; i < len; i++) {
169 char c = *(s + i);
170 if (!(c >= '0' && c <= '9')) {
171 return false;
172 }
173 }
174
175 return true;
176 }
177
178 /**
179 * @brief decode 32 bits as script array.
180 * 31-24 bits is script[0]
181 * 23-16 bits is script[1]
182 * 15-8 bits is script[2]
183 * 0-7 bits is script[3]
184 *
185 * @param encodeScript
186 * @param outValue
187 */
DecodeScript(uint32_t encodeScript,char * outValue)188 void Utils::DecodeScript(uint32_t encodeScript, char *outValue)
189 {
190 if (outValue == nullptr) {
191 return;
192 }
193 outValue[ArrayIndex::INDEX_ZERO] = (encodeScript & 0xFF000000) >> BitOperatorNum::BIT_TWENTY_FOUR;
194 outValue[ArrayIndex::INDEX_ONE] = (encodeScript & 0x00FF0000) >> BitOperatorNum::BIT_SIXTEEN;
195 outValue[ArrayIndex::INDEX_TWO] = (encodeScript & 0x0000FF00) >> BitOperatorNum::BIT_EIGHT;
196 outValue[ArrayIndex::INDEX_THREE] = (encodeScript & 0x000000FF);
197 }
198
IsStrEmpty(const char * s)199 bool Utils::IsStrEmpty(const char *s)
200 {
201 return (s == nullptr || *s == '\0');
202 }
203
StrLen(const char * s)204 size_t Utils::StrLen(const char *s)
205 {
206 if (s == nullptr) {
207 return 0;
208 }
209 return strlen(s);
210 }
211
EncodeLanguage(const char * language)212 uint16_t Utils::EncodeLanguage(const char *language)
213 {
214 if (Utils::IsStrEmpty(language)) {
215 return NULL_LANGUAGE;
216 }
217 return Utils::EncodeLanguageOrRegion(language, 'a');
218 }
219
220 /**
221 * @brief locale compose of language,script and region,encode as 64bits.
222 * 63-48 bits represent language,detail format see EncodeLanguageOrRegion method
223 * 47-16 bits represent script,detail format see EncodeScript method
224 * 15-0 bits represent region,detail format see EncodeLanguageOrRegion method
225 *
226 * @param language
227 * @param script
228 * @param region
229 * @return uint64_t
230 */
EncodeLocale(const char * language,const char * script,const char * region)231 uint64_t Utils::EncodeLocale(const char *language,
232 const char *script,
233 const char *region)
234 {
235 uint16_t languageData = Utils::EncodeLanguage(language);
236 uint32_t scriptData = Utils::EncodeScript(script);
237 uint16_t regionData = Utils::EncodeRegion(region);
238
239 return (uint64_t)(0xffff000000000000 & (((uint64_t)languageData) << BitOperatorNum::BIT_FORTY_EIGHT)) |
240 (0x0000ffffffff0000 & (((uint64_t)scriptData) << BitOperatorNum::BIT_SIXTEEN)) |
241 (0x000000000000ffff & (uint64_t)(regionData));
242 }
243
EncodeRegionByResLocale(const ResLocale * locale)244 uint16_t Utils::EncodeRegionByResLocale(const ResLocale *locale)
245 {
246 if (locale == nullptr) {
247 return NULL_REGION;
248 }
249 return Utils::EncodeRegion(locale->GetRegion());
250 }
251
EncodeLanguageByResLocale(const ResLocale * locale)252 uint16_t Utils::EncodeLanguageByResLocale(const ResLocale *locale)
253 {
254 if (locale == nullptr) {
255 return NULL_LANGUAGE;
256 }
257 return Utils::EncodeLanguage(locale->GetLanguage());
258 }
259
EncodeScriptByResLocale(const ResLocale * locale)260 uint32_t Utils::EncodeScriptByResLocale(const ResLocale *locale)
261 {
262 if (locale == nullptr) {
263 return NULL_SCRIPT;
264 }
265 return Utils::EncodeScript(locale->GetScript());
266 }
267
EncodeRegion(const char * region)268 uint16_t Utils::EncodeRegion(const char *region)
269 {
270 if (Utils::IsStrEmpty(region) || StrLen(region) < 1) {
271 return NULL_REGION;
272 }
273 if (region[0] >= '0' && region[0] <= '9') {
274 return Utils::EncodeLanguageOrRegion(region, '0');
275 }
276 return Utils::EncodeLanguageOrRegion(region, 'A');
277 }
278
279 /**
280 * @brief script is four letter array.encode script array as four bytes.Encode format.
281 * 31-24 bits represent script[0]
282 * 23-16 bits represent script[1]
283 * 15-8 bits represent script[2]
284 * 0-7 bits represent script[3]
285 *
286 * @param script
287 * @return uint32_t
288 */
EncodeScript(const char * script)289 uint32_t Utils::EncodeScript(const char *script)
290 {
291 if (Utils::IsStrEmpty(script) || StrLen(script) < ArrayLen::LEN_FOUR) {
292 return NULL_SCRIPT;
293 }
294 return ((uint8_t)script[ArrayIndex::INDEX_ZERO] << BitOperatorNum::BIT_TWENTY_FOUR) |
295 ((uint8_t)script[ArrayIndex::INDEX_ONE] << BitOperatorNum::BIT_SIXTEEN) |
296 ((uint8_t)script[ArrayIndex::INDEX_TWO] << BitOperatorNum::BIT_EIGHT) |
297 (uint8_t)script[ArrayIndex::INDEX_THREE];
298 }
299
300 /**
301 * @brief encode language or region str as two byte.
302 * language is two or three lowercase.
303 * region is two capital letter or three digit.
304 *
305 * two char,encode format
306 * 15-8 bits is the first char
307 * 7-0 bits is the second char
308 *
309 * three chars,encode format
310 * 15 bit is 1
311 * 14-10 bits represent the value of the first char subtract base char,
312 * 9-5 bits represent the value of the second char subtract base char .
313 * 4-0 bits represent the value of the third char subtract base char.
314 * base char is 'a','A','0'.
315 * example when base is 'a',max value('z' - 'a') is 26,so five bits can represent a char.
316 *
317 * @param str
318 * @param base is '0' or 'a' or 'A'
319 * @return uint16_t
320 */
EncodeLanguageOrRegion(const char * str,char base)321 uint16_t Utils::EncodeLanguageOrRegion(const char *str, char base)
322 {
323 if (str[ArrayIndex::INDEX_TWO] == 0 || str[ArrayIndex::INDEX_TWO] == '-' || str[ArrayIndex::INDEX_TWO] == '_') {
324 return ((uint8_t)str[ArrayIndex::INDEX_ZERO] << BitOperatorNum::BIT_EIGHT) |
325 ((uint8_t)str[ArrayIndex::INDEX_ONE]);
326 }
327 uint8_t first = ((uint8_t)(str[ArrayIndex::INDEX_ZERO] - base)) & 0x7f;
328 uint8_t second = ((uint8_t)(str[ArrayIndex::INDEX_ONE] - base)) & 0x7f;
329 uint8_t third = ((uint8_t)(str[ArrayIndex::INDEX_TWO] - base)) & 0x7f;
330 return ((0x80 | (first << BitOperatorNum::BIT_TWO) | (second >> BitOperatorNum::BIT_THREE)) <<
331 BitOperatorNum::BIT_EIGHT) | ((second << BitOperatorNum::BIT_FIVE) | third);
332 };
333
334 /**
335 * @brief convert hex char as int value
336 *
337 * @param c
338 * @param state
339 * @return uint32_t
340 */
ParseHex(char c,RState & state)341 static uint32_t ParseHex(char c, RState &state)
342 {
343 if (c >= '0' && c <= '9') {
344 return (c - '0');
345 } else if (c >= 'a' && c <= 'f') {
346 return (c - 'a' + 0xa);
347 } else if (c >= 'A' && c <= 'F') {
348 return (c - 'A' + 0xa);
349 }
350 state = INVALID_FORMAT;
351 return -1;
352 }
353
ConvertColorRgbToUInt32(const char * s,uint32_t & color,RState & parseState)354 void ConvertColorRgbToUInt32(const char *s, uint32_t &color, RState &parseState)
355 {
356 color |= 0xFF000000;
357 color |= ParseHex(s[ArrayIndex::INDEX_ONE], parseState) << BitOperatorNum::BIT_TWENTY;
358 color |= ParseHex(s[ArrayIndex::INDEX_ONE], parseState) << BitOperatorNum::BIT_SIXTEEN;
359 color |= ParseHex(s[ArrayIndex::INDEX_TWO], parseState) << BitOperatorNum::BIT_TWELVE;
360 color |= ParseHex(s[ArrayIndex::INDEX_TWO], parseState) << BitOperatorNum::BIT_EIGHT;
361 color |= ParseHex(s[ArrayIndex::INDEX_THREE], parseState) << BitOperatorNum::BIT_FOUR;
362 color |= ParseHex(s[ArrayIndex::INDEX_THREE], parseState);
363 }
364
ConvertColorArgbToUInt32(const char * s,uint32_t & color,RState & parseState)365 void ConvertColorArgbToUInt32(const char *s, uint32_t &color, RState &parseState)
366 {
367 color |= ParseHex(s[ArrayIndex::INDEX_ONE], parseState) << BitOperatorNum::BIT_TWENTY_EIGHT;
368 color |= ParseHex(s[ArrayIndex::INDEX_ONE], parseState) << BitOperatorNum::BIT_TWENTY_FOUR;
369 color |= ParseHex(s[ArrayIndex::INDEX_TWO], parseState) << BitOperatorNum::BIT_TWENTY;
370 color |= ParseHex(s[ArrayIndex::INDEX_TWO], parseState) << BitOperatorNum::BIT_SIXTEEN;
371 color |= ParseHex(s[ArrayIndex::INDEX_THREE], parseState) << BitOperatorNum::BIT_TWELVE;
372 color |= ParseHex(s[ArrayIndex::INDEX_THREE], parseState) << BitOperatorNum::BIT_EIGHT;
373 color |= ParseHex(s[ArrayIndex::INDEX_FOUR], parseState) << BitOperatorNum::BIT_FOUR;
374 color |= ParseHex(s[ArrayIndex::INDEX_FOUR], parseState);
375 }
376
ConvertColorSixRgbToUInt32(const char * s,uint32_t & color,RState & parseState)377 void ConvertColorSixRgbToUInt32(const char *s, uint32_t &color, RState &parseState)
378 {
379 color |= 0xFF000000;
380 color |= ParseHex(s[ArrayIndex::INDEX_ONE], parseState) << BitOperatorNum::BIT_TWENTY;
381 color |= ParseHex(s[ArrayIndex::INDEX_TWO], parseState) << BitOperatorNum::BIT_SIXTEEN;
382 color |= ParseHex(s[ArrayIndex::INDEX_THREE], parseState) << BitOperatorNum::BIT_TWELVE;
383 color |= ParseHex(s[ArrayIndex::INDEX_FOUR], parseState) << BitOperatorNum::BIT_EIGHT;
384 color |= ParseHex(s[ArrayIndex::INDEX_FIVE], parseState) << BitOperatorNum::BIT_FOUR;
385 color |= ParseHex(s[ArrayIndex::INDEX_SIX], parseState);
386 }
387
ConvertColorEightRgbToUInt32(const char * s,uint32_t & color,RState & parseState)388 void ConvertColorEightRgbToUInt32(const char *s, uint32_t &color, RState &parseState)
389 {
390 color |= ParseHex(s[ArrayIndex::INDEX_ONE], parseState) << BitOperatorNum::BIT_TWENTY_EIGHT;
391 color |= ParseHex(s[ArrayIndex::INDEX_TWO], parseState) << BitOperatorNum::BIT_TWENTY_FOUR;
392 color |= ParseHex(s[ArrayIndex::INDEX_THREE], parseState) << BitOperatorNum::BIT_TWENTY;
393 color |= ParseHex(s[ArrayIndex::INDEX_FOUR], parseState) << BitOperatorNum::BIT_SIXTEEN;
394 color |= ParseHex(s[ArrayIndex::INDEX_FIVE], parseState) << BitOperatorNum::BIT_TWELVE;
395 color |= ParseHex(s[ArrayIndex::INDEX_SIX], parseState) << BitOperatorNum::BIT_EIGHT;
396 color |= ParseHex(s[ArrayIndex::INDEX_SEVEN], parseState) << BitOperatorNum::BIT_FOUR;
397 color |= ParseHex(s[ArrayIndex::INDEX_EIGHT], parseState);
398 }
399
400 /**
401 * @brief convert color string to 32 bits value 0xaarrggbb.
402 * color string format is
403 * #rgb red (0-f) greed(0-f) blue(0-f)
404 * #argb transparency(0-f) red (0-f) greed(0-f) blue(0-f)
405 * #rrggbb red (00-ff) greed(00-ff) blue(00-ff)
406 * #aarrggbb transparency(00-ff) red (00-ff) greed(00-ff) blue(00-ff)
407 *
408 * @param s
409 * @param outValue
410 * @return RState
411 */
ConvertColorToUInt32(const char * s,uint32_t & outValue)412 RState Utils::ConvertColorToUInt32(const char *s, uint32_t &outValue)
413 {
414 if (s == nullptr) {
415 return INVALID_FORMAT;
416 }
417 uint32_t color = 0;
418 RState parseState = SUCCESS;
419 size_t len = strlen(s);
420 if (*s == '#') {
421 if (len == ArrayLen::LEN_FOUR) {
422 ConvertColorRgbToUInt32(s, color, parseState);
423 } else if (len == ArrayLen::LEN_FIVE) {
424 ConvertColorArgbToUInt32(s, color, parseState);
425 } else if (len == ArrayLen::LEN_SEVEN) {
426 ConvertColorSixRgbToUInt32(s, color, parseState);
427 } else if (len == ArrayLen::LEN_NINE) {
428 ConvertColorEightRgbToUInt32(s, color, parseState);
429 } else {
430 return INVALID_FORMAT;
431 }
432 } else {
433 parseState = INVALID_FORMAT;
434 }
435 outValue = color;
436 return parseState;
437 }
438
endWithTail(const std::string & path,const std::string & tail)439 bool Utils::endWithTail(const std::string& path, const std::string& tail)
440 {
441 if (path.size() < tail.size()) {
442 RESMGR_HILOGD(RESMGR_TAG, "the path is shorter than tail");
443 return false;
444 }
445 return path.compare(path.size() - tail.size(), tail.size(), tail) == 0;
446 }
447
IsFileExist(const std::string & filePath)448 bool Utils::IsFileExist(const std::string& filePath)
449 {
450 struct stat buffer;
451 return (stat(filePath.c_str(), &buffer) == 0);
452 }
453
ContainsTail(std::string hapPath,std::set<std::string> tailSet)454 bool Utils::ContainsTail(std::string hapPath, std::set<std::string> tailSet)
455 {
456 for (auto tail : tailSet) {
457 if (Utils::endWithTail(hapPath, tail)) {
458 return true;
459 }
460 }
461 return false;
462 }
463
CanonicalizePath(const char * path,char * outPath,size_t len)464 void Utils::CanonicalizePath(const char *path, char *outPath, size_t len)
465 {
466 #if !defined(__WINNT__) && !defined(__IDE_PREVIEW__) && !defined(__ARKUI_CROSS__)
467 HITRACE_METER_NAME_EX(HITRACE_LEVEL_INFO, HITRACE_TAG_APP, __PRETTY_FUNCTION__, nullptr);
468 #endif
469 if (path == nullptr) {
470 RESMGR_HILOGE(RESMGR_TAG, "path is null");
471 return;
472 }
473 if (strlen(path) >= len) {
474 RESMGR_HILOGE(RESMGR_TAG, "the length of path longer than len");
475 return;
476 }
477 #ifdef __WINNT__
478 if (!PathCanonicalizeA(outPath, path)) {
479 RESMGR_HILOGE(RESMGR_TAG, "failed to canonicalize the path");
480 return;
481 }
482 #else
483 if (realpath(path, outPath) == nullptr) {
484 RESMGR_HILOGE(RESMGR_TAG, "failed to realpath the path, errno:%{public}d", errno);
485 return;
486 }
487 #endif
488 }
489
GetFilesForWin(const std::string & strCurrentDir,std::vector<std::string> & vFiles)490 RState Utils::GetFilesForWin(const std::string &strCurrentDir, std::vector<std::string> &vFiles)
491 {
492 #if defined(__WINNT__) && defined(__IDE_PREVIEW__)
493 struct _finddata_t findData;
494 std::string findPath = strCurrentDir + "\\*.*";
495 intptr_t handle = _findfirst(findPath.c_str(), &findData);
496 if (handle == ERROR_RESULT) {
497 RESMGR_HILOGE(RESMGR_TAG, "invalid path, %{public}s", strCurrentDir.c_str());
498 return ERROR_CODE_RES_PATH_INVALID;
499 }
500
501 do {
502 if (strcmp(findData.name, ".") == 0 || strcmp(findData.name, "..") == 0) {
503 continue;
504 }
505 vFiles.emplace_back(findData.name);
506 } while (_findnext(handle, &findData) == 0);
507 _findclose(handle);
508 #endif
509 return SUCCESS;
510 }
511
GetFiles(const std::string & strCurrentDir,std::vector<std::string> & vFiles)512 RState Utils::GetFiles(const std::string &strCurrentDir, std::vector<std::string> &vFiles)
513 {
514 char outPath[PATH_MAX + 1] = {0};
515 Utils::CanonicalizePath(strCurrentDir.c_str(), outPath, PATH_MAX);
516 if (outPath[0] == '\0') {
517 RESMGR_HILOGE(RESMGR_TAG, "invalid path, %{public}s", strCurrentDir.c_str());
518 return ERROR_CODE_RES_PATH_INVALID;
519 }
520 #if !defined(__WINNT__)
521 DIR *dir;
522 struct dirent *pDir;
523 if ((dir = opendir(strCurrentDir.c_str())) == nullptr) {
524 RESMGR_HILOGE(RESMGR_TAG, "opendir failed strCurrentDir = %{public}s", strCurrentDir.c_str());
525 return ERROR_CODE_RES_PATH_INVALID;
526 }
527 while ((pDir = readdir(dir)) != nullptr) {
528 if (strcmp(pDir->d_name, ".") == 0 || strcmp(pDir->d_name, "..") == 0) {
529 continue;
530 }
531 if (pDir->d_type != DT_REG && pDir->d_type != DT_DIR) {
532 continue;
533 }
534 vFiles.emplace_back(pDir->d_name);
535 }
536 closedir(dir);
537 #else
538 return GetFilesForWin(strCurrentDir, vFiles);
539 #endif
540 return SUCCESS;
541 }
542
IsValidValue(const char * end,const std::string & str)543 bool Utils::IsValidValue(const char* end, const std::string& str)
544 {
545 if (end == str.c_str() || errno == ERANGE || *end != '\0') {
546 RESMGR_HILOGE(RESMGR_TAG, "invalid value = %{public}s, errno = %{public}d", str.c_str(), errno);
547 return false;
548 }
549 return true;
550 }
551
convertToInteger(const std::string & str,int & outValue)552 bool Utils::convertToInteger(const std::string& str, int& outValue)
553 {
554 char* end;
555 errno = 0;
556 long value = std::strtol(str.c_str(), &end, CONVERT_BASE);
557 if (!IsValidValue(end, str)) {
558 return false;
559 }
560 outValue = static_cast<int>(value);
561 return true;
562 }
563
convertToUnsignedLong(const std::string & str,unsigned long & outValue)564 bool Utils::convertToUnsignedLong(const std::string& str, unsigned long& outValue)
565 {
566 char* end;
567 errno = 0;
568 unsigned long value = std::strtoul(str.c_str(), &end, CONVERT_BASE);
569 if (!IsValidValue(end, str)) {
570 return false;
571 }
572 outValue = value;
573 return true;
574 }
575
convertToDouble(const std::string & str,double & outValue)576 bool Utils::convertToDouble(const std::string& str, double& outValue)
577 {
578 char* end;
579 errno = 0;
580 double value = std::strtod(str.c_str(), &end);
581 if (!IsValidValue(end, str)) {
582 return false;
583 }
584 outValue = value;
585 return true;
586 }
587
IsSystemPath(const std::string & path)588 bool Utils::IsSystemPath(const std::string& path)
589 {
590 return Utils::endWithTail(path, "/systemres/resources.index")
591 || Utils::endWithTail(path, "\\resources\\resources.index")
592 || Utils::endWithTail(path, "/resources/resources.index");
593 }
594
GetSystemParameter(const std::string & paramKey)595 std::string Utils::GetSystemParameter(const std::string& paramKey)
596 {
597 std::string paramValue;
598 #if !defined(__WINNT__) && !defined(__IDE_PREVIEW__) && !defined(__ARKUI_CROSS__)
599 paramValue = system::GetParameter(paramKey, "");
600 #endif
601 return paramValue;
602 }
603 } // namespace Resource
604 } // namespace Global
605 } // namespace OHOS
606