• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2021 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 "string_util.h"
16 #include <climits>
17 #include <iomanip>
18 #include <iostream>
19 #include <sstream>
20 #include <string>
21 #include <vector>
22 
23 namespace OHOS {
24 namespace HiviewDFX {
25 namespace StringUtil {
26 using namespace std;
27 const char INDICATE_VALUE_CHAR = ':';
28 const char KEY_VALUE_END_CHAR = ';';
29 constexpr int SKIP_NEXT_INDEX_LENGTH = 2;
30 const std::string EMPTY_STRING = "";
ConvertVectorToStr(const std::vector<std::string> & listStr,const std::string & split)31 std::string ConvertVectorToStr(const std::vector<std::string> &listStr, const std::string &split)
32 {
33     std::string str("");
34     for (auto &item : listStr) {
35         if (str == "") {
36             str = item;
37         } else {
38             str += split + item;
39         }
40     }
41     return str;
42 }
43 
ReplaceStr(const string & str,const string & src,const string & dst)44 string ReplaceStr(const string& str, const string& src, const string& dst)
45 {
46     if (src.empty()) {
47         return str;
48     }
49 
50     string::size_type pos = 0;
51     string strTmp = str;
52     while ((pos = strTmp.find(src, pos)) != string::npos) {
53         strTmp.replace(pos, src.length(), dst);
54         pos += dst.length();
55     }
56 
57     return strTmp;
58 }
59 
TrimStr(const string & str,const char cTrim)60 string TrimStr(const string& str, const char cTrim)
61 {
62     string strTmp = str;
63     strTmp.erase(0, strTmp.find_first_not_of(cTrim));
64     strTmp.erase(strTmp.find_last_not_of(cTrim) + sizeof(char));
65     return strTmp;
66 }
67 
SplitStr(const string & str,const string & sep,vector<string> & strs,bool canEmpty,bool needTrim)68 void SplitStr(const string& str, const string& sep, vector<string>& strs,
69               bool canEmpty, bool needTrim)
70 {
71     strs.clear();
72     string strTmp = needTrim ? TrimStr(str) : str;
73     string strPart;
74     while (true) {
75         string::size_type pos = strTmp.find(sep);
76         if (string::npos == pos || sep.empty()) {
77             strPart = needTrim ? TrimStr(strTmp) : strTmp;
78             if (!strPart.empty() || canEmpty) {
79                 strs.push_back(strPart);
80             }
81             break;
82         } else {
83             strPart = needTrim ? TrimStr(strTmp.substr(0, pos)) : strTmp.substr(0, pos);
84             if (!strPart.empty() || canEmpty) {
85                 strs.push_back(strPart);
86             }
87             strTmp = strTmp.substr(sep.size() + pos, strTmp.size() - sep.size() - pos);
88         }
89     }
90 }
91 
StrToInt(const string & str,int & value)92 bool StrToInt(const string& str, int& value)
93 {
94     if (str.empty() || (!isdigit(str.front()) && (str.front() != '-'))) {
95         return false;
96     }
97 
98     char* end = nullptr;
99     const int base = 10;
100     errno = 0;
101     auto addr = str.c_str();
102     auto result = strtol(addr, &end, base);
103     if (end == addr || end[0] != '\0' || errno == ERANGE) {
104         return false;
105     }
106 
107     value = static_cast<int>(result);
108     return true;
109 }
110 
StrToInt(const string & str)111 int StrToInt(const string& str)
112 {
113     int id = -1;
114     StrToInt(str, id);
115     return id;
116 }
117 
DexToHexString(int value,bool upper)118 string DexToHexString(int value, bool upper)
119 {
120     stringstream ioss;
121     string hexString;
122     if (upper) {
123         ioss << setiosflags(ios::uppercase) << hex << value;
124     } else {
125         ioss << hex << value;
126     }
127 
128     ioss >> hexString;
129     return hexString;
130 }
131 
GetKeyValueByString(size_t & start,const std::string & inputString)132 KeyValuePair GetKeyValueByString(size_t &start, const std::string &inputString)
133 {
134     std::string key;
135     std::string value;
136     auto length = inputString.size();
137     while (start < length) {
138         if (inputString[start] == INDICATE_VALUE_CHAR) {
139             start++;
140             break;
141         }
142         key.append(1, inputString[start]);
143         start++;
144     }
145 
146     while (start < length) {
147         if (inputString[start] == KEY_VALUE_END_CHAR) {
148             // replace ;; to ; in value;
149             // one ';' means the end of a "key:value;"
150             if (start + 1 < length && inputString[start + 1] == KEY_VALUE_END_CHAR) {
151                 value.append(1, inputString[start]);
152                 start = start + SKIP_NEXT_INDEX_LENGTH;
153                 continue;
154             } else {
155                 start++;
156                 break;
157             }
158         }
159         if (inputString[start] == INDICATE_VALUE_CHAR && start + 1 < length &&
160             inputString[start + 1] == INDICATE_VALUE_CHAR) {
161             // replace :: to :
162             value.append(1, inputString[start]);
163             start = start + SKIP_NEXT_INDEX_LENGTH;
164             continue;
165         }
166         value.append(1, inputString[start]);
167         start++;
168     }
169     return make_pair(key, make_pair(value, 0));
170 }
171 
IsValidFloatNum(const std::string & value)172 bool IsValidFloatNum(const std::string &value)
173 {
174     int len = value.size();
175     int pointNum = 0;
176 
177     for (int i = 0; i < len; i++) {
178         if (isdigit(value[i])) {
179             continue;
180         }
181         if (value[i] == '.') {
182             pointNum++;
183         } else {
184             // the string contains not valid num;
185             return false;
186         }
187     }
188     // the string contains more than one character '.'
189     if (pointNum > 1) {
190         return false;
191     }
192     // the string format is .111/111.
193     return isdigit(value[0]) && isdigit(value[len - 1]);
194 }
195 
SplitStr(const std::string & str,char delimiter)196 std::list<std::string> SplitStr(const std::string& str, char delimiter)
197 {
198     std::list<std::string> tokens;
199     std::string token;
200     std::istringstream tokenStream(str);
201     while (std::getline(tokenStream, token, delimiter)) {
202         tokens.push_back(token);
203     }
204     return tokens;
205 }
206 
GetLeftSubstr(const string & input,const string & split)207 string GetLeftSubstr(const string& input, const string& split)
208 {
209     size_t pos = input.find(split, 0);
210     if (pos == string::npos) {
211         return input;
212     }
213     return input.substr(0, pos);
214 }
215 
GetRightSubstr(const string & input,const string & split)216 string GetRightSubstr(const string& input, const string& split)
217 {
218     size_t pos = input.find(split, 0);
219     if (pos == string::npos) {
220         return "none";
221     }
222     return input.substr(pos + split.size(), input.size() - pos);
223 }
224 
GetRleftSubstr(const string & input,const string & split)225 string GetRleftSubstr(const string& input, const string& split)
226 {
227     size_t pos = input.rfind(split, string::npos);
228     if (pos == string::npos) {
229         return input;
230     }
231     return input.substr(0, pos);
232 }
233 
GetRrightSubstr(const string & input,const string & split)234 string GetRrightSubstr(const string& input, const string& split)
235 {
236     size_t pos = input.rfind(split, string::npos);
237     if (pos == string::npos) {
238         return "none";
239     }
240     return input.substr(pos + 1, input.size() - pos);
241 }
242 
EraseString(const string & input,const string & toErase)243 string EraseString(const string& input, const string& toErase)
244 {
245     size_t pos = 0;
246     string out = input;
247     while ((pos = out.find(toErase, pos)) != string::npos) {
248         out.erase(pos, toErase.size());
249         pos = (pos == 0) ? (0) : (pos - 1);
250     }
251     return out;
252 }
253 
GetMidSubstr(const string & input,const string & begin,const string & end)254 string GetMidSubstr(const string& input, const string& begin, const string& end)
255 {
256     string midstr = "";
257     size_t beginPos = input.find(begin, 0);
258     if (beginPos == string::npos) {
259         return midstr;
260     }
261     beginPos = beginPos + begin.size();
262     size_t endPos = input.find(end, beginPos);
263     if (endPos == string::npos) {
264         return midstr;
265     }
266     return input.substr(beginPos, endPos - beginPos);
267 }
268 
VectorToString(const vector<string> & src,bool reverse,const string & tag)269 string VectorToString(const vector<string>& src, bool reverse, const string& tag)
270 {
271     string str;
272     for (auto element : src) {
273         if (element.empty()) {
274             continue;
275         }
276         if (reverse) {
277             str = element + tag + str;
278         } else {
279             str = str + element + tag;
280         }
281     }
282     return str;
283 }
284 
StringToUl(const string & flag,int base)285 uint64_t StringToUl(const string& flag, int base)
286 {
287     uint64_t ret = strtoul(flag.c_str(), NULL, base);
288     if (ret == ULONG_MAX) {
289         return 0;
290     }
291     return ret;
292 }
293 
StringToDouble(const string & input)294 double StringToDouble(const string& input)
295 {
296     if (input.empty()) {
297         return 0;
298     }
299     char *e = nullptr;
300     errno = 0;
301     double temp = std::strtod(input.c_str(), &e);
302 
303     if (errno != 0) { // error, overflow or underflow
304         return 0;
305     }
306     return temp;
307 }
308 
FindMatchSubString(const std::string & target,const std::string & begin,int offset,const std::string & end)309 std::string FindMatchSubString(const std::string& target, const std::string& begin, int offset,
310     const std::string& end)
311 {
312     auto matchPos = target.find_first_of(begin);
313     if (matchPos == std::string::npos) {
314         return "";
315     }
316     auto beginPos = matchPos + offset;
317     if (beginPos > target.length()) {
318         return "";
319     }
320     auto endPos = target.find_first_of(end, beginPos);
321     if (endPos == std::string::npos) {
322         return target.substr(beginPos);
323     }
324     return target.substr(beginPos, endPos);
325 }
326 
EscapeJsonStringValue(const std::string & value)327 std::string EscapeJsonStringValue(const std::string &value)
328 {
329     std::string escapeValue;
330     for (auto it = value.begin(); it != value.end(); it++) {
331         switch (*it) {
332             case '\\':
333                 escapeValue.push_back('\\');
334                 escapeValue.push_back('\\');
335                 break;
336             case '\"':
337                 escapeValue.push_back('\\');
338                 escapeValue.push_back('"');
339                 break;
340             case '\b':
341                 escapeValue.push_back('\\');
342                 escapeValue.push_back('b');
343                 break;
344             case '\f':
345                 escapeValue.push_back('\\');
346                 escapeValue.push_back('f');
347                 break;
348             case '\n':
349                 escapeValue.push_back('\\');
350                 escapeValue.push_back('n');
351                 break;
352             case '\r':
353                 escapeValue.push_back('\\');
354                 escapeValue.push_back('r');
355                 break;
356             case '\t':
357                 escapeValue.push_back('\\');
358                 escapeValue.push_back('t');
359                 break;
360             default:
361                 escapeValue.push_back(*it);
362                 break;
363         }
364     }
365     return escapeValue;
366 }
367 
UnescapeJsonStringValue(const std::string & value)368 std::string UnescapeJsonStringValue(const std::string &value)
369 {
370     bool isEscaped = true;
371     std::string unescapeValue;
372     for (auto it = value.begin(); it != value.end(); it++) {
373         if (isEscaped) {
374             switch (*it) {
375                 case '"':
376                     unescapeValue.push_back('\"');
377                     break;
378                 case '/':
379                     unescapeValue.push_back('/');
380                     break;
381                 case 'b':
382                     unescapeValue.push_back('\b');
383                     break;
384                 case 'f':
385                     unescapeValue.push_back('\f');
386                     break;
387                 case 'n':
388                     unescapeValue.push_back('\n');
389                     break;
390                 case 'r':
391                     unescapeValue.push_back('\r');
392                     break;
393                 case 't':
394                     unescapeValue.push_back('\t');
395                     break;
396                 case '\\':
397                     unescapeValue.push_back('\\');
398                     break;
399                 default:
400                     unescapeValue.push_back(*it);
401                     break;
402             }
403             isEscaped = false;
404         } else {
405             switch (*it) {
406                 case '\\':
407                     isEscaped = true;
408                     break;
409                 default:
410                     unescapeValue.push_back(*it);
411                     break;
412             }
413         }
414     }
415     return unescapeValue;
416 }
417 } // namespace StringUtil
418 } // namespace HiviewDFX
419 } // namespace OHOS
420