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