• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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