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