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