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