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