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