1 /* 2 * Copyright (c) 2023 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 16 #ifndef STRING_UTILS_H 17 #define STRING_UTILS_H 18 19 #include <algorithm> 20 #include <charconv> 21 #include <functional> 22 #include <string> 23 #include <vector> 24 25 #define GET_ENUM_VALUE_STRING(item) StringUtils::GetEnumValueString(#item) 26 27 namespace OHOS { 28 namespace UpdateService { 29 30 enum class StrCnvResult { 31 SUCCESS, 32 FAILED, 33 INVALID_CHAR, 34 NUMBER_FORMAT_ERROR, 35 SPILL_OVER, 36 }; 37 38 class StringUtils { 39 public: 40 // trim from start (in place) LTrim(std::string & inputStr)41 static inline void LTrim(std::string &inputStr) 42 { 43 inputStr.erase(inputStr.begin(), 44 std::find_if(inputStr.begin(), inputStr.end(), [](unsigned char ch) { return !std::isspace(ch); })); 45 } 46 47 // trim from end (in place) RTrim(std::string & inputStr)48 static inline void RTrim(std::string &inputStr) 49 { 50 inputStr.erase( 51 std::find_if(inputStr.rbegin(), inputStr.rend(), [](unsigned char ch) { return !std::isspace(ch); }).base(), 52 inputStr.end()); 53 } 54 55 // trim from both ends (in place) Trim(std::string & inputStr)56 static inline void Trim(std::string &inputStr) 57 { 58 LTrim(inputStr); 59 RTrim(inputStr); 60 } 61 Split(const std::string & str,char delimiter)62 static inline std::vector<std::string> Split(const std::string &str, char delimiter) 63 { 64 std::vector<std::string> tokens; 65 size_t start; 66 size_t end = 0; 67 while ((start = str.find_first_not_of(delimiter, end)) != std::string::npos) { 68 end = str.find(delimiter, start); 69 tokens.push_back(str.substr(start, end - start)); 70 } 71 return tokens; 72 } 73 GetBoolStr(bool isTrue)74 static inline std::string GetBoolStr(bool isTrue) 75 { 76 return isTrue ? "true" : "false"; 77 } 78 SafeSubString(const std::string & sourceStr,int beginIndex,int endIndex,std::string defaultStr)79 static std::string SafeSubString(const std::string &sourceStr, int beginIndex, int endIndex, 80 std::string defaultStr) 81 { 82 if (sourceStr.empty()) { 83 return defaultStr; 84 } 85 if (beginIndex < 0 || static_cast<size_t>(endIndex) > sourceStr.size() || beginIndex > endIndex) { 86 return defaultStr; 87 } 88 return sourceStr.substr(beginIndex, endIndex); 89 } 90 GetEnumValueString(const std::string & enumItem)91 static std::string GetEnumValueString(const std::string &enumItem) 92 { 93 std::string enumSplit = "::"; 94 size_t split = enumItem.find(enumSplit); 95 if (split == std::string::npos) { 96 return ""; 97 } 98 return enumItem.substr(split + enumSplit.length(), enumItem.length()); 99 } 100 GetLastSplitString(const std::string & stringName,const std::string & splitStr)101 static std::string GetLastSplitString(const std::string &stringName, const std::string &splitStr) 102 { 103 std::size_t found = stringName.find_last_of(splitStr); 104 std::string fileString = ""; 105 if (found != std::string::npos) { 106 fileString = stringName.substr(found + 1, stringName.size()); 107 } 108 return fileString; 109 } 110 ReplaceStringAll(std::string & srcString,const std::string & subString,const std::string & newString)111 static void ReplaceStringAll(std::string &srcString, const std::string &subString, const std::string &newString) 112 { 113 std::string resultString = srcString; 114 for (std::string::size_type pos = 0; pos != std::string::npos; pos += newString.length()) { 115 pos = resultString.find(subString, pos); 116 if (pos != std::string::npos) { 117 resultString.replace(pos, subString.length(), newString); 118 } else { 119 break; 120 } 121 } 122 srcString = resultString; 123 } 124 StringRemove(std::string & sourceString,const std::string & startString,const std::string & endString)125 static void StringRemove(std::string &sourceString, const std::string &startString, 126 const std::string &endString) 127 { 128 if (sourceString.empty()) { 129 return; 130 } 131 std::string::size_type indexStart = sourceString.find(startString); 132 if (indexStart != std::string::npos) { 133 std::string::size_type indexEnd = sourceString.find(endString, indexStart); 134 if (indexEnd != std::string::npos) { 135 std::string tmpString = sourceString.substr(0, indexStart) + 136 sourceString.substr(indexEnd + endString.length(), sourceString.length()); 137 sourceString = tmpString; 138 } 139 } 140 return; 141 } 142 DecStringToNumber(const std::string & str,T & number)143 template <typename T>[[maybe_unused]] static StrCnvResult DecStringToNumber(const std::string &str, T &number) 144 { 145 constexpr int numberBase = 10; 146 return StringToNumberInner(str, number, numberBase); 147 } 148 149 private: 150 template <typename T> StringToNumberInner(const std::string & str,T & number,int base)151 [[maybe_unused]] static StrCnvResult StringToNumberInner(const std::string &str, T &number, int base) 152 { 153 T numTemp; 154 std::string strTemp = str; 155 Trim(strTemp); 156 auto result = std::from_chars(strTemp.data(), strTemp.data() + strTemp.size(), numTemp, base); 157 if (result.ec == std::errc::result_out_of_range) { 158 return StrCnvResult::SPILL_OVER; 159 } 160 if (result.ec != std::errc()) { 161 return StrCnvResult::FAILED; 162 } 163 number = numTemp; 164 // 判断字符串是否含有特殊字符 例如"100a" 165 if (result.ptr != strTemp.data() + strTemp.size()) { 166 return StrCnvResult::INVALID_CHAR; 167 } 168 // 防止字符串前后空格导致解析错误,使得数据可以解析,是否使用由调用者自己判断 169 if (strTemp.size() != str.size()) { 170 return StrCnvResult::NUMBER_FORMAT_ERROR; 171 } 172 return StrCnvResult::SUCCESS; 173 } 174 }; 175 } // namespace UpdateService 176 } // namespace OHOS 177 #endif // STRING_UTILS_H