• 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 
16 #include "string_ex.h"
17 #include "unicode_ex.h"
18 #include "utils_log.h"
19 #include <iomanip>
20 #include <sstream>
21 using namespace std;
22 
23 namespace OHOS {
24 
25 static const int CHAR16_TO_CHAR8_PARAM_INVALID = -1;
26 static const int CHAR16_TO_CHAR8_EMPTY_STR = -2;
27 static const int CHAR16_TO_CHAR8_INSUFFICIENT_BUFFER = -3;
28 
UpperStr(const string & str)29 string UpperStr(const string& str)
30 {
31     string upperString = str;
32     transform(upperString.begin(), upperString.end(), upperString.begin(), ::toupper);
33     return upperString;
34 }
35 
LowerStr(const string & str)36 string LowerStr(const string& str)
37 {
38     string lowerString = str;
39     transform(lowerString.begin(), lowerString.end(), lowerString.begin(), ::tolower);
40     return lowerString;
41 }
42 
ReplaceStr(const string & str,const string & src,const string & dst)43 string ReplaceStr(const string& str, const string& src, const string& dst)
44 {
45     if (src.empty()) {
46         return str;
47     }
48 
49     string::size_type pos = 0;
50     string strTmp = str;
51     while ((pos = strTmp.find(src, pos)) != string::npos) {
52         strTmp.replace(pos, src.length(), dst);
53         pos += dst.length();
54     }
55 
56     return strTmp;
57 }
58 
TrimStr(const string & str,const char cTrim)59 string TrimStr(const string& str, const char cTrim /*= ' '*/)
60 {
61     if (str.size() == 1 && str[0] == cTrim) {
62         return string{};
63     }
64 
65     string strTmp = str;
66     std::string::size_type firstBound = strTmp.find_first_not_of(cTrim);
67     if (firstBound != std::string::npos) {
68         strTmp.erase(0, firstBound);
69     }
70 
71     std::string::size_type lastBound = strTmp.find_last_not_of(cTrim);
72     if (lastBound != std::string::npos && lastBound != strTmp.size() - 1) {
73         strTmp.erase(lastBound + sizeof(char));
74     }
75 
76     return strTmp;
77 }
78 
DexToHexString(int value,bool upper)79 string DexToHexString(int value, bool upper /*= true*/)
80 {
81     stringstream ioss;
82     string hexString;
83     if (upper) {
84         ioss << setiosflags(ios::uppercase) << hex << value;
85     } else {
86         ioss << hex << value;
87     }
88 
89     ioss >> hexString;
90     return hexString;
91 }
92 
SplitStr(const string & str,const string & sep,vector<string> & strs,bool canEmpty,bool needTrim)93 void SplitStr(const string& str, const string& sep, vector<string>& strs, bool canEmpty, bool needTrim)
94 {
95     strs.clear();
96     string strTmp = needTrim ? TrimStr(str) : str;
97     string strPart;
98     while (true) {
99         string::size_type pos = strTmp.find(sep);
100         if (string::npos == pos || sep.empty()) {
101             strPart = needTrim ? TrimStr(strTmp) : strTmp;
102             if (!strPart.empty() || canEmpty) {
103                 strs.push_back(strPart);
104             }
105             break;
106         } else {
107             strPart = needTrim ? TrimStr(strTmp.substr(0, pos)) : strTmp.substr(0, pos);
108             if (!strPart.empty() || canEmpty) {
109                 strs.push_back(strPart);
110             }
111             strTmp = strTmp.substr(sep.size() + pos, strTmp.size() - sep.size() - pos);
112         }
113     }
114 }
115 
StrToInt(const string & str,int & value)116 bool StrToInt(const string& str, int& value)
117 {
118     if (str.empty() || (!isdigit(str.front()) && (str.front() != '-'))) {
119         return false;
120     }
121 
122     char* end = nullptr;
123     errno = 0;
124     auto addr = str.c_str();
125     auto result = strtol(addr, &end, 10); /* 10 means decimal */
126     if ((end == addr) || (end[0] != '\0') || (errno == ERANGE) ||
127             (result > INT_MAX) || (result < INT_MIN)) {
128         return false;
129     }
130     value = static_cast<int>(result);
131     return true;
132 }
133 
IsNumericStr(const string & str)134 bool IsNumericStr(const string& str)
135 {
136     if (str.empty()) {
137         return false;
138     }
139 
140     for (const auto& c : str) {
141         if (!isdigit(c)) {
142             return false;
143         }
144     }
145 
146     return true;
147 }
148 
IsAlphaStr(const string & str)149 bool IsAlphaStr(const string& str)
150 {
151     if (str.empty()) {
152         return false;
153     }
154 
155     for (const auto& c : str) {
156         if (!isalpha(c)) {
157             return false;
158         }
159     }
160 
161     return true;
162 }
163 
IsUpperStr(const string & str)164 bool IsUpperStr(const string& str)
165 {
166     if (str.empty()) {
167         return false;
168     }
169 
170     for (const auto& c : str) {
171         if (!isupper(c)) {
172             return false;
173         }
174     }
175 
176     return true;
177 }
178 
IsLowerStr(const string & str)179 bool IsLowerStr(const string& str)
180 {
181     if (str.empty()) {
182         return false;
183     }
184 
185     for (const auto& c : str) {
186         if (!islower(c)) {
187             return false;
188         }
189     }
190 
191     return true;
192 }
193 
IsSubStr(const string & str,const string & sub)194 bool IsSubStr(const string& str, const string& sub)
195 {
196     if (sub.empty() || str.empty()) {
197         return false;
198     }
199 
200     return str.find(sub) != string::npos;
201 }
202 
GetFirstSubStrBetween(const string & str,const string & left,const string & right,string & sub)203 string::size_type GetFirstSubStrBetween(const string& str, const string& left,
204     const string& right, string& sub)
205 {
206     string::size_type leftPos = str.find(left);
207     if (leftPos == string::npos) {
208         return string::npos;
209     }
210 
211     string::size_type rightPos = str.find(right, leftPos + left.length());
212     if (rightPos == string::npos) {
213         return string::npos;
214     }
215 
216     sub = str.substr((leftPos + left.length()), (rightPos - (leftPos + left.length())));
217     return rightPos;
218 }
219 
GetSubStrBetween(const string & str,const string & left,const string & right,vector<string> & sub)220 void GetSubStrBetween(const string& str, const string& left, const string& right, vector<string>& sub)
221 {
222     string subString;
223     string strTmp = str;
224     string::size_type pos = GetFirstSubStrBetween(strTmp, left, right, subString);
225     while (pos != string::npos) {
226         sub.push_back(subString);
227         strTmp = strTmp.substr(pos);
228         pos = GetFirstSubStrBetween(strTmp, left, right, subString);
229     }
230 }
231 
IsSameTextStr(const string & first,const string & second)232 bool IsSameTextStr(const string& first, const string& second)
233 {
234     return UpperStr(first) == UpperStr(second);
235 }
236 
237 /*
238  * utf8 rule
239  * 0000 ~ 007F        : 0xxxxxxx
240  * 0080 ~ 07FF        : 110xxxxx 10xxxxxx
241  * 0800 ~ FFFF        : 1110xxxx 10xxxxxx 10xxxxxx
242  * 10000 ~ 1FFFFF     : 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx
243  */
IsAsciiString(const string & str)244 bool IsAsciiString(const string& str)
245 {
246     size_t strLen = str.length();
247     for (size_t i = 0; i < strLen; ++i) {
248         if ((str[i] & 0x80) != 0) {
249             return false;
250         }
251     }
252 
253     return true;
254 }
255 
256 #ifndef IOS_PLATFORM
Str8ToStr16(const string & str)257 u16string Str8ToStr16(const string& str)
258 {
259     u16string str16Value;
260     if (!String8ToString16(str, str16Value)) {
261         return u16string();
262     }
263 
264     return str16Value;
265 }
266 
Str16ToStr8(const u16string & str16)267 string Str16ToStr8(const u16string& str16)
268 {
269     string str8Value;
270     if (!String16ToString8(str16, str8Value)) {
271         return string();
272     }
273 
274     return str8Value;
275 }
276 
GetUtf16ToUtf8Length(const u16string & str16)277 int GetUtf16ToUtf8Length(const u16string& str16)
278 {
279     size_t str16Len = str16.length();
280     if (str16Len == 0) {
281         return -1;
282     }
283     const char16_t *utf16Str = str16.c_str();
284     return Utf16ToUtf8Length(utf16Str, str16Len);
285 }
286 
Char16ToChar8(const u16string & str16,char * buffer,int bufferLen)287 int Char16ToChar8(const u16string& str16, char *buffer, int bufferLen)
288 {
289     if (buffer == nullptr || bufferLen <= 0) {
290         return CHAR16_TO_CHAR8_PARAM_INVALID;
291     }
292     size_t str16Len = str16.length();
293     if (str16Len == 0) {
294         return CHAR16_TO_CHAR8_EMPTY_STR;
295     }
296     const char16_t *utf16Str = str16.c_str();
297     int utf8Len = Utf16ToUtf8Length(utf16Str, str16Len);
298     if (utf8Len < 0 || utf8Len >= INT_MAX || (utf8Len + 1) > bufferLen) {
299         UTILS_LOGD("utf8buffer len:%{public}d, actual buffer len:%{public}d!", utf8Len + 1, bufferLen);
300         return CHAR16_TO_CHAR8_INSUFFICIENT_BUFFER;
301     }
302     StrncpyStr16ToStr8(utf16Str, str16Len, buffer, utf8Len + 1);
303     return utf8Len + 1;
304 }
305 
306 #endif
307 } // namespace OHOS
308