• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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