* Copyright (c) 2021-2026 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "utils.h"
#include <cerrno>
#include <climits>
#include <fstream>
#include <stdexcept>
#include <string>
#include <unistd.h>
#include <vector>
#include "locale_config.h"
#include "localebuilder.h"
#include "log.h"
#include "ohos/init_data.h"
#include "stage_asset_manager.h"
namespace OHOS {
namespace Global {
namespace I18n {
using namespace std;
const size_t HEX_PAIR_LENGTH = 2;
const int32_t HEX_BASE = 16;
const double DOUBLE_EPSILON = 1e-6;
void Split(const string &src, const string &sep, vector<string> &dest)
{
if (src == "") {
return;
}
string::size_type begin = 0;
string::size_type end = src.find(sep);
while (end != string::npos) {
dest.push_back(src.substr(begin, end - begin));
begin = end + sep.size();
end = src.find(sep, begin);
}
if (begin != src.size()) {
dest.push_back(src.substr(begin));
}
}
int32_t ConvertString2Int(const string &numberStr, int32_t& status)
{
if (numberStr.empty()) {
status = -1;
return -1;
}
try {
return std::stoi(numberStr);
} catch(const std::invalid_argument& except) {
status = -1;
return -1;
} catch (const std::out_of_range& except) {
status = -1;
return -1;
}
}
void GetAllValidLocalesTag(std::unordered_set<std::string>& allValidLocalesLanguageTag)
{
static bool init = false;
if (init) {
return;
}
int32_t validCount = 1;
const icu::Locale *validLocales = icu::Locale::getAvailableLocales(validCount);
for (int i = 0; i < validCount; i++) {
allValidLocalesLanguageTag.insert(validLocales[i].getLanguage());
}
init = true;
}
bool IsValidLocaleTag(icu::Locale &locale)
{
static std::unordered_set<std::string> allValidLocalesLanguageTag;
GetAllValidLocalesTag(allValidLocalesLanguageTag);
std::string languageTag = locale.getLanguage();
if (allValidLocalesLanguageTag.find(languageTag) == allValidLocalesLanguageTag.end()) {
LOGE("GetTimePeriodName does not support this languageTag: %{public}s", languageTag.c_str());
return false;
}
return true;
}
std::string GetAppDataModuleDir()
{
#ifdef ANDROID_PLATFORM
std::string appDataModuleDir =
OHOS::AbilityRuntime::Platform::StageAssetManager::GetInstance()->GetAppDataModuleDir();
#else
std::string appDataModuleDir =
OHOS::AbilityRuntime::Platform::StageAssetManager::GetInstance()->GetBundleCodeDir();
#endif
appDataModuleDir = appDataModuleDir + "/" + "systemres";
return appDataModuleDir;
}
void I18nSetArkUIXIcuDirectory()
{
std::string appDataModuleDir = GetAppDataModuleDir();
LOGI("appDataModuleDir: %{public}s", appDataModuleDir.c_str());
SetArkuiXIcuDirectory(appDataModuleDir.c_str());
}
void Split(const std::string& src, const std::string& sep, std::unordered_set<std::string>& dest)
{
dest.clear();
if (src.empty()) {
return;
}
std::string::size_type begin = 0;
std::string::size_type end = src.find(sep);
while (end != string::npos) {
dest.insert(src.substr(begin, end - begin));
begin = end + sep.size();
end = src.find(sep, begin);
}
if (begin != src.size()) {
dest.insert(src.substr(begin));
}
}
std::string GetAbsoluteFilePath(const std::string& filePath)
{
if (filePath.empty()) {
LOGE("utils::GetAbsoluteFilePath: input param filePath is empty");
return "";
}
std::vector<char> resolvedPath(PATH_MAX + 1);
if (realpath(filePath.c_str(), resolvedPath.data()) == nullptr) {
LOGE("utils::GetAbsoluteFilePath realpath error, error message: %{public}s.", strerror(errno));
return "";
}
resolvedPath[PATH_MAX] = '\0';
std::ifstream file(resolvedPath.data());
if (!file.good()) {
LOGE("utils::GetAbsoluteFilePath file open is not good.");
return "";
}
return std::string(resolvedPath.data());
}
std::string StrReplaceAll(const std::string& str,
const std::string& target, const std::string& replace)
{
std::string::size_type pos = 0;
std::string result = str;
if (replace.empty() || target.compare(replace) == 0) {
return result;
}
while ((pos = result.find(target)) != std::string::npos) {
result.replace(pos, target.length(), replace);
}
return result;
}
bool Eq(double a, double b)
{
return fabs(a - b) < DOUBLE_EPSILON;
}
bool Geq(double a, double b)
{
return a > b || Eq(a, b);
}
bool Leq(double a, double b)
{
return a < b || Eq(a, b);
}
bool FileExist(const std::string& path)
{
int isFileExist = access(path.c_str(), F_OK);
bool resultFileExist = isFileExist == -1 ? false : true;
return resultFileExist;
}
std::string trim(std::string& s)
{
if (s.empty()) {
return s;
}
s.erase(0, s.find_first_not_of(" "));
s.erase(s.find_last_not_of(" ") + 1);
return s;
}
std::string GetISO3Language(const std::string& language)
{
UErrorCode icuStatus = U_ZERO_ERROR;
icu::Locale locale = icu::Locale::forLanguageTag(language.data(), icuStatus);
if (U_FAILURE(icuStatus) || !IsValidLocaleTag(locale)) {
return "";
}
return locale.getISO3Language();
}
std::string GetISO3Country(const std::string& country)
{
UErrorCode icuStatus = U_ZERO_ERROR;
icu::Locale locale;
if (LocaleConfig::IsValidRegion(country)) {
locale = icu::LocaleBuilder().setLanguage("zh").setRegion(country).build(icuStatus);
} else if (LocaleConfig::IsValidTag(country)) {
locale = icu::Locale::forLanguageTag(country.data(), icuStatus);
} else {
return "";
}
if (U_FAILURE(icuStatus) || !IsValidLocaleTag(locale)) {
return "";
}
return locale.getISO3Country();
}
void Merge(const std::vector<std::string>& src, const std::string& sep, std::string& dest)
{
if (src.size() == 0) {
dest = "";
return;
}
dest = src[0];
for (size_t i = 1; i < src.size(); ++i) {
dest += sep;
dest += src[i];
}
}
bool RegexSearchNoExcept(const std::string& str, std::smatch& match, const std::regex& regex)
{
try {
return std::regex_search(str, match, regex);
} catch (const std::regex_error &except) {
LOGE("RegexSearchNoExcept: regex_error caught %{public}s.", except.what());
return false;
}
}
std::string HexToStr(const std::string& hex)
{
size_t len = HEX_PAIR_LENGTH;
if (hex.length() % len != 0) {
return "";
}
bool flag = true;
std::string result;
for (size_t i = 0; i < hex.length(); i += len) {
std::string hexStr = hex.substr(i, len);
if (flag && hexStr.compare("00") == 0) {
continue;
}
flag = false;
int32_t value = 0;
try {
value = std::stoi(hexStr, nullptr, HEX_BASE);
} catch (const std::invalid_argument &except) {
LOGE("HexToStr: invalid_argument, hexStr: %{public}s.", hexStr.c_str());
return "";
} catch (const std::out_of_range &except) {
LOGE("HexToStr: out_of_range, hexStr: %{public}s.", hexStr.c_str());
return "";
} catch (...) {
LOGE("HexToStr: unknow error, hexStr: %{public}s.", hexStr.c_str());
return "";
}
result += char(value);
}
return result;
}
}
}
}