13f4cbf05Sopenharmony_ci/*
23f4cbf05Sopenharmony_ci * Copyright (c) 2021 Huawei Device Co., Ltd.
33f4cbf05Sopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License");
43f4cbf05Sopenharmony_ci * you may not use this file except in compliance with the License.
53f4cbf05Sopenharmony_ci * You may obtain a copy of the License at
63f4cbf05Sopenharmony_ci *
73f4cbf05Sopenharmony_ci *     http://www.apache.org/licenses/LICENSE-2.0
83f4cbf05Sopenharmony_ci *
93f4cbf05Sopenharmony_ci * Unless required by applicable law or agreed to in writing, software
103f4cbf05Sopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS,
113f4cbf05Sopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
123f4cbf05Sopenharmony_ci * See the License for the specific language governing permissions and
133f4cbf05Sopenharmony_ci * limitations under the License.
143f4cbf05Sopenharmony_ci */
153f4cbf05Sopenharmony_ci
163f4cbf05Sopenharmony_ci#include "string_ex.h"
173f4cbf05Sopenharmony_ci#include "unicode_ex.h"
183f4cbf05Sopenharmony_ci#include "utils_log.h"
193f4cbf05Sopenharmony_ci#include "securec.h"
203f4cbf05Sopenharmony_ci#include <iostream>
213f4cbf05Sopenharmony_ci#include <iomanip>
223f4cbf05Sopenharmony_ci#include <sstream>
233f4cbf05Sopenharmony_ciusing namespace std;
243f4cbf05Sopenharmony_ci
253f4cbf05Sopenharmony_cinamespace OHOS {
263f4cbf05Sopenharmony_ci
273f4cbf05Sopenharmony_cistatic const int CHAR16_TO_CHAR8_PARAM_INVALID = -1;
283f4cbf05Sopenharmony_cistatic const int CHAR16_TO_CHAR8_EMPTY_STR = -2;
293f4cbf05Sopenharmony_cistatic const int CHAR16_TO_CHAR8_INSUFFICIENT_BUFFER = -3;
303f4cbf05Sopenharmony_ci
313f4cbf05Sopenharmony_cistring UpperStr(const string& str)
323f4cbf05Sopenharmony_ci{
333f4cbf05Sopenharmony_ci    string upperString = str;
343f4cbf05Sopenharmony_ci    transform(upperString.begin(), upperString.end(), upperString.begin(), ::toupper);
353f4cbf05Sopenharmony_ci    return upperString;
363f4cbf05Sopenharmony_ci}
373f4cbf05Sopenharmony_ci
383f4cbf05Sopenharmony_cistring LowerStr(const string& str)
393f4cbf05Sopenharmony_ci{
403f4cbf05Sopenharmony_ci    string lowerString = str;
413f4cbf05Sopenharmony_ci    transform(lowerString.begin(), lowerString.end(), lowerString.begin(), ::tolower);
423f4cbf05Sopenharmony_ci    return lowerString;
433f4cbf05Sopenharmony_ci}
443f4cbf05Sopenharmony_ci
453f4cbf05Sopenharmony_cistring ReplaceStr(const string& str, const string& src, const string& dst)
463f4cbf05Sopenharmony_ci{
473f4cbf05Sopenharmony_ci    if (src.empty()) {
483f4cbf05Sopenharmony_ci        return str;
493f4cbf05Sopenharmony_ci    }
503f4cbf05Sopenharmony_ci
513f4cbf05Sopenharmony_ci    string::size_type pos = 0;
523f4cbf05Sopenharmony_ci    string strTmp = str;
533f4cbf05Sopenharmony_ci    while ((pos = strTmp.find(src, pos)) != string::npos) {
543f4cbf05Sopenharmony_ci        strTmp.replace(pos, src.length(), dst);
553f4cbf05Sopenharmony_ci        pos += dst.length();
563f4cbf05Sopenharmony_ci    }
573f4cbf05Sopenharmony_ci
583f4cbf05Sopenharmony_ci    return strTmp;
593f4cbf05Sopenharmony_ci}
603f4cbf05Sopenharmony_ci
613f4cbf05Sopenharmony_cistring TrimStr(const string& str, const char cTrim /*= ' '*/)
623f4cbf05Sopenharmony_ci{
633f4cbf05Sopenharmony_ci    if (str.size() == 1 && str[0] == cTrim) {
643f4cbf05Sopenharmony_ci        return string{};
653f4cbf05Sopenharmony_ci    }
663f4cbf05Sopenharmony_ci
673f4cbf05Sopenharmony_ci    string strTmp = str;
683f4cbf05Sopenharmony_ci    std::string::size_type firstBound = strTmp.find_first_not_of(cTrim);
693f4cbf05Sopenharmony_ci    if (firstBound != std::string::npos) {
703f4cbf05Sopenharmony_ci        strTmp.erase(0, firstBound);
713f4cbf05Sopenharmony_ci    }
723f4cbf05Sopenharmony_ci
733f4cbf05Sopenharmony_ci    std::string::size_type lastBound = strTmp.find_last_not_of(cTrim);
743f4cbf05Sopenharmony_ci    if (lastBound != std::string::npos && lastBound != strTmp.size() - 1) {
753f4cbf05Sopenharmony_ci        strTmp.erase(lastBound + sizeof(char));
763f4cbf05Sopenharmony_ci    }
773f4cbf05Sopenharmony_ci
783f4cbf05Sopenharmony_ci    return strTmp;
793f4cbf05Sopenharmony_ci}
803f4cbf05Sopenharmony_ci
813f4cbf05Sopenharmony_cistring DexToHexString(int value, bool upper /*= true*/)
823f4cbf05Sopenharmony_ci{
833f4cbf05Sopenharmony_ci    stringstream ioss;
843f4cbf05Sopenharmony_ci    string hexString;
853f4cbf05Sopenharmony_ci    if (upper) {
863f4cbf05Sopenharmony_ci        ioss << setiosflags(ios::uppercase) << hex << value;
873f4cbf05Sopenharmony_ci    } else {
883f4cbf05Sopenharmony_ci        ioss << hex << value;
893f4cbf05Sopenharmony_ci    }
903f4cbf05Sopenharmony_ci
913f4cbf05Sopenharmony_ci    ioss >> hexString;
923f4cbf05Sopenharmony_ci    return hexString;
933f4cbf05Sopenharmony_ci}
943f4cbf05Sopenharmony_ci
953f4cbf05Sopenharmony_civoid SplitStr(const string& str, const string& sep, vector<string>& strs, bool canEmpty, bool needTrim)
963f4cbf05Sopenharmony_ci{
973f4cbf05Sopenharmony_ci    strs.clear();
983f4cbf05Sopenharmony_ci    string strTmp = needTrim ? TrimStr(str) : str;
993f4cbf05Sopenharmony_ci    string strPart;
1003f4cbf05Sopenharmony_ci    while (true) {
1013f4cbf05Sopenharmony_ci        string::size_type pos = strTmp.find(sep);
1023f4cbf05Sopenharmony_ci        if (string::npos == pos || sep.empty()) {
1033f4cbf05Sopenharmony_ci            strPart = needTrim ? TrimStr(strTmp) : strTmp;
1043f4cbf05Sopenharmony_ci            if (!strPart.empty() || canEmpty) {
1053f4cbf05Sopenharmony_ci                strs.push_back(strPart);
1063f4cbf05Sopenharmony_ci            }
1073f4cbf05Sopenharmony_ci            break;
1083f4cbf05Sopenharmony_ci        } else {
1093f4cbf05Sopenharmony_ci            strPart = needTrim ? TrimStr(strTmp.substr(0, pos)) : strTmp.substr(0, pos);
1103f4cbf05Sopenharmony_ci            if (!strPart.empty() || canEmpty) {
1113f4cbf05Sopenharmony_ci                strs.push_back(strPart);
1123f4cbf05Sopenharmony_ci            }
1133f4cbf05Sopenharmony_ci            strTmp = strTmp.substr(sep.size() + pos, strTmp.size() - sep.size() - pos);
1143f4cbf05Sopenharmony_ci        }
1153f4cbf05Sopenharmony_ci    }
1163f4cbf05Sopenharmony_ci}
1173f4cbf05Sopenharmony_ci
1183f4cbf05Sopenharmony_cibool StrToInt(const string& str, int& value)
1193f4cbf05Sopenharmony_ci{
1203f4cbf05Sopenharmony_ci    if (str.empty() || (!isdigit(str.front()) && (str.front() != '-'))) {
1213f4cbf05Sopenharmony_ci        return false;
1223f4cbf05Sopenharmony_ci    }
1233f4cbf05Sopenharmony_ci
1243f4cbf05Sopenharmony_ci    char* end = nullptr;
1253f4cbf05Sopenharmony_ci    errno = 0;
1263f4cbf05Sopenharmony_ci    auto addr = str.c_str();
1273f4cbf05Sopenharmony_ci    auto result = strtol(addr, &end, 10); /* 10 means decimal */
1283f4cbf05Sopenharmony_ci    if ((end == addr) || (end[0] != '\0') || (errno == ERANGE) ||
1293f4cbf05Sopenharmony_ci            (result > INT_MAX) || (result < INT_MIN)) {
1303f4cbf05Sopenharmony_ci        return false;
1313f4cbf05Sopenharmony_ci    }
1323f4cbf05Sopenharmony_ci    value = static_cast<int>(result);
1333f4cbf05Sopenharmony_ci    return true;
1343f4cbf05Sopenharmony_ci}
1353f4cbf05Sopenharmony_ci
1363f4cbf05Sopenharmony_cibool IsNumericStr(const string& str)
1373f4cbf05Sopenharmony_ci{
1383f4cbf05Sopenharmony_ci    if (str.empty()) {
1393f4cbf05Sopenharmony_ci        return false;
1403f4cbf05Sopenharmony_ci    }
1413f4cbf05Sopenharmony_ci
1423f4cbf05Sopenharmony_ci    for (const auto& c : str) {
1433f4cbf05Sopenharmony_ci        if (!isdigit(c)) {
1443f4cbf05Sopenharmony_ci            return false;
1453f4cbf05Sopenharmony_ci        }
1463f4cbf05Sopenharmony_ci    }
1473f4cbf05Sopenharmony_ci
1483f4cbf05Sopenharmony_ci    return true;
1493f4cbf05Sopenharmony_ci}
1503f4cbf05Sopenharmony_ci
1513f4cbf05Sopenharmony_cibool IsAlphaStr(const string& str)
1523f4cbf05Sopenharmony_ci{
1533f4cbf05Sopenharmony_ci    if (str.empty()) {
1543f4cbf05Sopenharmony_ci        return false;
1553f4cbf05Sopenharmony_ci    }
1563f4cbf05Sopenharmony_ci
1573f4cbf05Sopenharmony_ci    for (const auto& c : str) {
1583f4cbf05Sopenharmony_ci        if (!isalpha(c)) {
1593f4cbf05Sopenharmony_ci            return false;
1603f4cbf05Sopenharmony_ci        }
1613f4cbf05Sopenharmony_ci    }
1623f4cbf05Sopenharmony_ci
1633f4cbf05Sopenharmony_ci    return true;
1643f4cbf05Sopenharmony_ci}
1653f4cbf05Sopenharmony_ci
1663f4cbf05Sopenharmony_cibool IsUpperStr(const string& str)
1673f4cbf05Sopenharmony_ci{
1683f4cbf05Sopenharmony_ci    if (str.empty()) {
1693f4cbf05Sopenharmony_ci        return false;
1703f4cbf05Sopenharmony_ci    }
1713f4cbf05Sopenharmony_ci
1723f4cbf05Sopenharmony_ci    for (const auto& c : str) {
1733f4cbf05Sopenharmony_ci        if (!isupper(c)) {
1743f4cbf05Sopenharmony_ci            return false;
1753f4cbf05Sopenharmony_ci        }
1763f4cbf05Sopenharmony_ci    }
1773f4cbf05Sopenharmony_ci
1783f4cbf05Sopenharmony_ci    return true;
1793f4cbf05Sopenharmony_ci}
1803f4cbf05Sopenharmony_ci
1813f4cbf05Sopenharmony_cibool IsLowerStr(const string& str)
1823f4cbf05Sopenharmony_ci{
1833f4cbf05Sopenharmony_ci    if (str.empty()) {
1843f4cbf05Sopenharmony_ci        return false;
1853f4cbf05Sopenharmony_ci    }
1863f4cbf05Sopenharmony_ci
1873f4cbf05Sopenharmony_ci    for (const auto& c : str) {
1883f4cbf05Sopenharmony_ci        if (!islower(c)) {
1893f4cbf05Sopenharmony_ci            return false;
1903f4cbf05Sopenharmony_ci        }
1913f4cbf05Sopenharmony_ci    }
1923f4cbf05Sopenharmony_ci
1933f4cbf05Sopenharmony_ci    return true;
1943f4cbf05Sopenharmony_ci}
1953f4cbf05Sopenharmony_ci
1963f4cbf05Sopenharmony_cibool IsSubStr(const string& str, const string& sub)
1973f4cbf05Sopenharmony_ci{
1983f4cbf05Sopenharmony_ci    if (sub.empty() || str.empty()) {
1993f4cbf05Sopenharmony_ci        return false;
2003f4cbf05Sopenharmony_ci    }
2013f4cbf05Sopenharmony_ci
2023f4cbf05Sopenharmony_ci    return str.find(sub) != string::npos;
2033f4cbf05Sopenharmony_ci}
2043f4cbf05Sopenharmony_ci
2053f4cbf05Sopenharmony_cistring::size_type GetFirstSubStrBetween(const string& str, const string& left,
2063f4cbf05Sopenharmony_ci    const string& right, string& sub)
2073f4cbf05Sopenharmony_ci{
2083f4cbf05Sopenharmony_ci    string::size_type leftPos = str.find(left);
2093f4cbf05Sopenharmony_ci    if (leftPos == string::npos) {
2103f4cbf05Sopenharmony_ci        return string::npos;
2113f4cbf05Sopenharmony_ci    }
2123f4cbf05Sopenharmony_ci
2133f4cbf05Sopenharmony_ci    string::size_type rightPos = str.find(right, leftPos + left.length());
2143f4cbf05Sopenharmony_ci    if (rightPos == string::npos) {
2153f4cbf05Sopenharmony_ci        return string::npos;
2163f4cbf05Sopenharmony_ci    }
2173f4cbf05Sopenharmony_ci
2183f4cbf05Sopenharmony_ci    sub = str.substr((leftPos + left.length()), (rightPos - (leftPos + left.length())));
2193f4cbf05Sopenharmony_ci    return rightPos;
2203f4cbf05Sopenharmony_ci}
2213f4cbf05Sopenharmony_ci
2223f4cbf05Sopenharmony_civoid GetSubStrBetween(const string& str, const string& left, const string& right, vector<string>& sub)
2233f4cbf05Sopenharmony_ci{
2243f4cbf05Sopenharmony_ci    string subString;
2253f4cbf05Sopenharmony_ci    string strTmp = str;
2263f4cbf05Sopenharmony_ci    string::size_type pos = GetFirstSubStrBetween(strTmp, left, right, subString);
2273f4cbf05Sopenharmony_ci    while (pos != string::npos) {
2283f4cbf05Sopenharmony_ci        sub.push_back(subString);
2293f4cbf05Sopenharmony_ci        strTmp = strTmp.substr(pos);
2303f4cbf05Sopenharmony_ci        pos = GetFirstSubStrBetween(strTmp, left, right, subString);
2313f4cbf05Sopenharmony_ci    }
2323f4cbf05Sopenharmony_ci}
2333f4cbf05Sopenharmony_ci
2343f4cbf05Sopenharmony_cibool IsSameTextStr(const string& first, const string& second)
2353f4cbf05Sopenharmony_ci{
2363f4cbf05Sopenharmony_ci    return UpperStr(first) == UpperStr(second);
2373f4cbf05Sopenharmony_ci}
2383f4cbf05Sopenharmony_ci
2393f4cbf05Sopenharmony_ci/*
2403f4cbf05Sopenharmony_ci * utf8 rule
2413f4cbf05Sopenharmony_ci * 0000 ~ 007F        : 0xxxxxxx
2423f4cbf05Sopenharmony_ci * 0080 ~ 07FF        : 110xxxxx 10xxxxxx
2433f4cbf05Sopenharmony_ci * 0800 ~ FFFF        : 1110xxxx 10xxxxxx 10xxxxxx
2443f4cbf05Sopenharmony_ci * 10000 ~ 1FFFFF     : 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx
2453f4cbf05Sopenharmony_ci */
2463f4cbf05Sopenharmony_cibool IsAsciiString(const string& str)
2473f4cbf05Sopenharmony_ci{
2483f4cbf05Sopenharmony_ci    size_t strLen = str.length();
2493f4cbf05Sopenharmony_ci    for (size_t i = 0; i < strLen; ++i) {
2503f4cbf05Sopenharmony_ci        if ((str[i] & 0x80) != 0) {
2513f4cbf05Sopenharmony_ci            return false;
2523f4cbf05Sopenharmony_ci        }
2533f4cbf05Sopenharmony_ci    }
2543f4cbf05Sopenharmony_ci
2553f4cbf05Sopenharmony_ci    return true;
2563f4cbf05Sopenharmony_ci}
2573f4cbf05Sopenharmony_ci
2583f4cbf05Sopenharmony_ci#ifndef IOS_PLATFORM
2593f4cbf05Sopenharmony_ciu16string Str8ToStr16(const string& str)
2603f4cbf05Sopenharmony_ci{
2613f4cbf05Sopenharmony_ci    u16string str16Value;
2623f4cbf05Sopenharmony_ci    if (!String8ToString16(str, str16Value)) {
2633f4cbf05Sopenharmony_ci        return u16string();
2643f4cbf05Sopenharmony_ci    }
2653f4cbf05Sopenharmony_ci
2663f4cbf05Sopenharmony_ci    return str16Value;
2673f4cbf05Sopenharmony_ci}
2683f4cbf05Sopenharmony_ci
2693f4cbf05Sopenharmony_cistring Str16ToStr8(const u16string& str16)
2703f4cbf05Sopenharmony_ci{
2713f4cbf05Sopenharmony_ci    string str8Value;
2723f4cbf05Sopenharmony_ci    if (!String16ToString8(str16, str8Value)) {
2733f4cbf05Sopenharmony_ci        return string();
2743f4cbf05Sopenharmony_ci    }
2753f4cbf05Sopenharmony_ci
2763f4cbf05Sopenharmony_ci    return str8Value;
2773f4cbf05Sopenharmony_ci}
2783f4cbf05Sopenharmony_ci
2793f4cbf05Sopenharmony_ciint GetUtf16ToUtf8Length(const u16string& str16)
2803f4cbf05Sopenharmony_ci{
2813f4cbf05Sopenharmony_ci    size_t str16Len = str16.length();
2823f4cbf05Sopenharmony_ci    if (str16Len == 0) {
2833f4cbf05Sopenharmony_ci        return -1;
2843f4cbf05Sopenharmony_ci    }
2853f4cbf05Sopenharmony_ci    const char16_t *utf16Str = str16.c_str();
2863f4cbf05Sopenharmony_ci    return Utf16ToUtf8Length(utf16Str, str16Len);
2873f4cbf05Sopenharmony_ci}
2883f4cbf05Sopenharmony_ci
2893f4cbf05Sopenharmony_ciint Char16ToChar8(const u16string& str16, char *buffer, int bufferLen)
2903f4cbf05Sopenharmony_ci{
2913f4cbf05Sopenharmony_ci    if (buffer == nullptr || bufferLen <= 0) {
2923f4cbf05Sopenharmony_ci        return CHAR16_TO_CHAR8_PARAM_INVALID;
2933f4cbf05Sopenharmony_ci    }
2943f4cbf05Sopenharmony_ci    size_t str16Len = str16.length();
2953f4cbf05Sopenharmony_ci    if (str16Len == 0) {
2963f4cbf05Sopenharmony_ci        return CHAR16_TO_CHAR8_EMPTY_STR;
2973f4cbf05Sopenharmony_ci    }
2983f4cbf05Sopenharmony_ci    const char16_t *utf16Str = str16.c_str();
2993f4cbf05Sopenharmony_ci    int utf8Len = Utf16ToUtf8Length(utf16Str, str16Len);
3003f4cbf05Sopenharmony_ci    if (utf8Len < 0 || utf8Len >= INT_MAX || (utf8Len + 1) > bufferLen) {
3013f4cbf05Sopenharmony_ci        UTILS_LOGD("utf8buffer len:%{public}d, actual buffer len:%{public}d!", utf8Len + 1, bufferLen);
3023f4cbf05Sopenharmony_ci        return CHAR16_TO_CHAR8_INSUFFICIENT_BUFFER;
3033f4cbf05Sopenharmony_ci    }
3043f4cbf05Sopenharmony_ci    StrncpyStr16ToStr8(utf16Str, str16Len, buffer, utf8Len + 1);
3053f4cbf05Sopenharmony_ci    return utf8Len + 1;
3063f4cbf05Sopenharmony_ci}
3073f4cbf05Sopenharmony_ci
3083f4cbf05Sopenharmony_ci#endif
3093f4cbf05Sopenharmony_ci} // namespace OHOS
310