199552fe9Sopenharmony_ci/*
299552fe9Sopenharmony_ci * Copyright (c) 2023 Huawei Device Co., Ltd.
399552fe9Sopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License");
499552fe9Sopenharmony_ci * you may not use this file except in compliance with the License.
599552fe9Sopenharmony_ci * You may obtain a copy of the License at
699552fe9Sopenharmony_ci *
799552fe9Sopenharmony_ci *     http://www.apache.org/licenses/LICENSE-2.0
899552fe9Sopenharmony_ci *
999552fe9Sopenharmony_ci * Unless required by applicable law or agreed to in writing, software
1099552fe9Sopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS,
1199552fe9Sopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1299552fe9Sopenharmony_ci * See the License for the specific language governing permissions and
1399552fe9Sopenharmony_ci * limitations under the License.
1499552fe9Sopenharmony_ci */
1599552fe9Sopenharmony_ci
1699552fe9Sopenharmony_ci#include "json_utils.h"
1799552fe9Sopenharmony_ci
1899552fe9Sopenharmony_ci#include <climits>
1999552fe9Sopenharmony_ci#include <fcntl.h>
2099552fe9Sopenharmony_ci#include <fstream>
2199552fe9Sopenharmony_ci#include <sstream>
2299552fe9Sopenharmony_ci#include <unistd.h>
2399552fe9Sopenharmony_ci#include <vector>
2499552fe9Sopenharmony_ci
2599552fe9Sopenharmony_ci#include "standby_service_log.h"
2699552fe9Sopenharmony_ci
2799552fe9Sopenharmony_cinamespace OHOS {
2899552fe9Sopenharmony_cinamespace DevStandbyMgr {
2999552fe9Sopenharmony_cinamespace {
3099552fe9Sopenharmony_ci    constexpr uint32_t JSON_FORMAT = 4;
3199552fe9Sopenharmony_ci}
3299552fe9Sopenharmony_ci
3399552fe9Sopenharmony_cibool JsonUtils::LoadJsonValueFromContent(nlohmann::json& jsonValue, const std::string& content)
3499552fe9Sopenharmony_ci{
3599552fe9Sopenharmony_ci    if (content.empty()) {
3699552fe9Sopenharmony_ci        STANDBYSERVICE_LOGE("content is empty");
3799552fe9Sopenharmony_ci        return false;
3899552fe9Sopenharmony_ci    }
3999552fe9Sopenharmony_ci    jsonValue = nlohmann::json::parse(content, nullptr, false);
4099552fe9Sopenharmony_ci    if (jsonValue.is_discarded()) {
4199552fe9Sopenharmony_ci        STANDBYSERVICE_LOGE("failed to parse content");
4299552fe9Sopenharmony_ci        return false;
4399552fe9Sopenharmony_ci    }
4499552fe9Sopenharmony_ci    if (!jsonValue.is_object()) {
4599552fe9Sopenharmony_ci        STANDBYSERVICE_LOGE("the content is not an object");
4699552fe9Sopenharmony_ci        return false;
4799552fe9Sopenharmony_ci    }
4899552fe9Sopenharmony_ci    return true;
4999552fe9Sopenharmony_ci}
5099552fe9Sopenharmony_ci
5199552fe9Sopenharmony_cibool JsonUtils::LoadJsonValueFromFile(nlohmann::json& jsonValue, const std::string& filePath)
5299552fe9Sopenharmony_ci{
5399552fe9Sopenharmony_ci    std::string content;
5499552fe9Sopenharmony_ci    if (!GetFileContent(filePath, content)) {
5599552fe9Sopenharmony_ci        STANDBYSERVICE_LOGE("failed to load content from %{public}s", filePath.c_str());
5699552fe9Sopenharmony_ci        return false;
5799552fe9Sopenharmony_ci    }
5899552fe9Sopenharmony_ci    if (content.empty()) {
5999552fe9Sopenharmony_ci        STANDBYSERVICE_LOGE("content of %{public}s is empty", filePath.c_str());
6099552fe9Sopenharmony_ci        return false;
6199552fe9Sopenharmony_ci    }
6299552fe9Sopenharmony_ci    jsonValue = nlohmann::json::parse(content, nullptr, false);
6399552fe9Sopenharmony_ci    if (jsonValue.is_discarded()) {
6499552fe9Sopenharmony_ci        STANDBYSERVICE_LOGE("failed to parse content from %{public}s", filePath.c_str());
6599552fe9Sopenharmony_ci        return false;
6699552fe9Sopenharmony_ci    }
6799552fe9Sopenharmony_ci    if (!jsonValue.is_object()) {
6899552fe9Sopenharmony_ci        STANDBYSERVICE_LOGE("the content of %{public}s is not an object ", filePath.c_str());
6999552fe9Sopenharmony_ci        return false;
7099552fe9Sopenharmony_ci    }
7199552fe9Sopenharmony_ci    return true;
7299552fe9Sopenharmony_ci}
7399552fe9Sopenharmony_ci
7499552fe9Sopenharmony_cibool JsonUtils::DumpJsonValueToFile(const nlohmann::json& jsonValue, const std::string& filePath)
7599552fe9Sopenharmony_ci{
7699552fe9Sopenharmony_ci    if (!CreateNodeFile(filePath)) {
7799552fe9Sopenharmony_ci        STANDBYSERVICE_LOGE("create file failed.");
7899552fe9Sopenharmony_ci        return false;
7999552fe9Sopenharmony_ci    }
8099552fe9Sopenharmony_ci    std::ofstream fout;
8199552fe9Sopenharmony_ci    std::string realPath;
8299552fe9Sopenharmony_ci    if (!GetRealPath(filePath, realPath)) {
8399552fe9Sopenharmony_ci        STANDBYSERVICE_LOGE("get real file path: %{public}s failed", filePath.c_str());
8499552fe9Sopenharmony_ci        return false;
8599552fe9Sopenharmony_ci    }
8699552fe9Sopenharmony_ci    fout.open(realPath, std::ios::out);
8799552fe9Sopenharmony_ci    if (!fout.is_open()) {
8899552fe9Sopenharmony_ci        STANDBYSERVICE_LOGE("open file: %{public}s failed.", filePath.c_str());
8999552fe9Sopenharmony_ci        return false;
9099552fe9Sopenharmony_ci    }
9199552fe9Sopenharmony_ci    fout << jsonValue.dump(JSON_FORMAT).c_str() << std::endl;
9299552fe9Sopenharmony_ci    fout.close();
9399552fe9Sopenharmony_ci    return true;
9499552fe9Sopenharmony_ci}
9599552fe9Sopenharmony_ci
9699552fe9Sopenharmony_cibool JsonUtils::CreateNodeFile(const std::string &filePath)
9799552fe9Sopenharmony_ci{
9899552fe9Sopenharmony_ci    if (access(filePath.c_str(), F_OK) == ERR_OK) {
9999552fe9Sopenharmony_ci        STANDBYSERVICE_LOGD("the standby service config file: %{public}s already exists.", filePath.c_str());
10099552fe9Sopenharmony_ci        return true;
10199552fe9Sopenharmony_ci    }
10299552fe9Sopenharmony_ci    std::string fullpath {""};
10399552fe9Sopenharmony_ci    if (!GetRealPath(filePath, fullpath)) {
10499552fe9Sopenharmony_ci        STANDBYSERVICE_LOGD("the standby service config file: %{public}s not exists.", filePath.c_str());
10599552fe9Sopenharmony_ci        fullpath = filePath;
10699552fe9Sopenharmony_ci    }
10799552fe9Sopenharmony_ci    int32_t fd = open(fullpath.c_str(), O_CREAT|O_RDWR, S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH);
10899552fe9Sopenharmony_ci    if (fd < ERR_OK) {
10999552fe9Sopenharmony_ci        STANDBYSERVICE_LOGE("Fail to open file: %{public}s", fullpath.c_str());
11099552fe9Sopenharmony_ci        return false;
11199552fe9Sopenharmony_ci    }
11299552fe9Sopenharmony_ci    close(fd);
11399552fe9Sopenharmony_ci    return true;
11499552fe9Sopenharmony_ci}
11599552fe9Sopenharmony_ci
11699552fe9Sopenharmony_cibool JsonUtils::GetInt32FromJsonValue(const nlohmann::json& jsonValue, const std::string& key, int32_t& value)
11799552fe9Sopenharmony_ci{
11899552fe9Sopenharmony_ci    if (jsonValue.empty() || key.empty()) {
11999552fe9Sopenharmony_ci        return false;
12099552fe9Sopenharmony_ci    }
12199552fe9Sopenharmony_ci    if (jsonValue.contains(key) == 0 || !jsonValue.at(key).is_number_integer()) {
12299552fe9Sopenharmony_ci        return false;
12399552fe9Sopenharmony_ci    }
12499552fe9Sopenharmony_ci    value =  jsonValue.at(key).get<int32_t>();
12599552fe9Sopenharmony_ci    return true;
12699552fe9Sopenharmony_ci}
12799552fe9Sopenharmony_ci
12899552fe9Sopenharmony_cibool JsonUtils::GetBoolFromJsonValue(const nlohmann::json& jsonValue, const std::string& key, bool& value)
12999552fe9Sopenharmony_ci{
13099552fe9Sopenharmony_ci    if (jsonValue.empty() || key.empty()) {
13199552fe9Sopenharmony_ci        return false;
13299552fe9Sopenharmony_ci    }
13399552fe9Sopenharmony_ci    if (jsonValue.contains(key) == 0 || !jsonValue.at(key).is_boolean()) {
13499552fe9Sopenharmony_ci        return false;
13599552fe9Sopenharmony_ci    }
13699552fe9Sopenharmony_ci    value =  jsonValue.at(key).get<bool>();
13799552fe9Sopenharmony_ci    return true;
13899552fe9Sopenharmony_ci}
13999552fe9Sopenharmony_ci
14099552fe9Sopenharmony_cibool JsonUtils::GetStringFromJsonValue(const nlohmann::json& jsonValue, const std::string& key, std::string& value)
14199552fe9Sopenharmony_ci{
14299552fe9Sopenharmony_ci    if (jsonValue.empty() || key.empty()) {
14399552fe9Sopenharmony_ci        return false;
14499552fe9Sopenharmony_ci    }
14599552fe9Sopenharmony_ci    if (jsonValue.contains(key) == 0 || !jsonValue.at(key).is_string()) {
14699552fe9Sopenharmony_ci        return false;
14799552fe9Sopenharmony_ci    }
14899552fe9Sopenharmony_ci    value =  jsonValue.at(key).get<std::string>();
14999552fe9Sopenharmony_ci    return true;
15099552fe9Sopenharmony_ci}
15199552fe9Sopenharmony_ci
15299552fe9Sopenharmony_cibool JsonUtils::GetObjFromJsonValue(const nlohmann::json& jsonValue, const std::string& key, nlohmann::json& value)
15399552fe9Sopenharmony_ci{
15499552fe9Sopenharmony_ci    if (jsonValue.empty() || key.empty()) {
15599552fe9Sopenharmony_ci        return false;
15699552fe9Sopenharmony_ci    }
15799552fe9Sopenharmony_ci    if (jsonValue.contains(key) == 0 || !jsonValue.at(key).is_object()) {
15899552fe9Sopenharmony_ci        return false;
15999552fe9Sopenharmony_ci    }
16099552fe9Sopenharmony_ci    value =  jsonValue.at(key);
16199552fe9Sopenharmony_ci    return true;
16299552fe9Sopenharmony_ci}
16399552fe9Sopenharmony_ci
16499552fe9Sopenharmony_cibool JsonUtils::GetArrayFromJsonValue(const nlohmann::json& jsonValue, const std::string& key, nlohmann::json& value)
16599552fe9Sopenharmony_ci{
16699552fe9Sopenharmony_ci    if (jsonValue.empty() || key.empty()) {
16799552fe9Sopenharmony_ci        return false;
16899552fe9Sopenharmony_ci    }
16999552fe9Sopenharmony_ci    if (jsonValue.contains(key) == 0 || !jsonValue.at(key).is_array()) {
17099552fe9Sopenharmony_ci        return false;
17199552fe9Sopenharmony_ci    }
17299552fe9Sopenharmony_ci    value =  jsonValue.at(key);
17399552fe9Sopenharmony_ci    return true;
17499552fe9Sopenharmony_ci}
17599552fe9Sopenharmony_ci
17699552fe9Sopenharmony_cibool JsonUtils::GetStrArrFromJsonValue(const nlohmann::json& jsonValue, const std::string& key,
17799552fe9Sopenharmony_ci    std::vector<std::string>& strArray)
17899552fe9Sopenharmony_ci{
17999552fe9Sopenharmony_ci    nlohmann::json strArrayValue;
18099552fe9Sopenharmony_ci    if (!JsonUtils::GetArrayFromJsonValue(jsonValue, key, strArrayValue)) {
18199552fe9Sopenharmony_ci        return false;
18299552fe9Sopenharmony_ci    }
18399552fe9Sopenharmony_ci    strArray.clear();
18499552fe9Sopenharmony_ci    for (const auto &strItem : strArrayValue) {
18599552fe9Sopenharmony_ci        if (!strItem.is_string()) {
18699552fe9Sopenharmony_ci            return false;
18799552fe9Sopenharmony_ci        }
18899552fe9Sopenharmony_ci        strArray.emplace_back(strItem.get<std::string>());
18999552fe9Sopenharmony_ci    }
19099552fe9Sopenharmony_ci    return true;
19199552fe9Sopenharmony_ci}
19299552fe9Sopenharmony_ci
19399552fe9Sopenharmony_cibool JsonUtils::GetFileContent(const std::string& filePath, std::string& content)
19499552fe9Sopenharmony_ci{
19599552fe9Sopenharmony_ci    std::string fullPath;
19699552fe9Sopenharmony_ci    if (!GetRealPath(filePath, fullPath)) {
19799552fe9Sopenharmony_ci        return false;
19899552fe9Sopenharmony_ci    }
19999552fe9Sopenharmony_ci    STANDBYSERVICE_LOGD("full path of standby service config file is: %{public}s ", fullPath.c_str());
20099552fe9Sopenharmony_ci    std::ifstream fin(fullPath);
20199552fe9Sopenharmony_ci    if (!fin.is_open()) {
20299552fe9Sopenharmony_ci        return false;
20399552fe9Sopenharmony_ci    }
20499552fe9Sopenharmony_ci    std::ostringstream ss;
20599552fe9Sopenharmony_ci    ss << fin.rdbuf();
20699552fe9Sopenharmony_ci    content = ss.str();
20799552fe9Sopenharmony_ci    return true;
20899552fe9Sopenharmony_ci}
20999552fe9Sopenharmony_ci
21099552fe9Sopenharmony_cibool JsonUtils::GetRealPath(const std::string& partialPath, std::string& fullPath)
21199552fe9Sopenharmony_ci{
21299552fe9Sopenharmony_ci    char tmpPath[PATH_MAX] = {0};
21399552fe9Sopenharmony_ci    if (partialPath.size() > PATH_MAX || !realpath(partialPath.c_str(), tmpPath)) {
21499552fe9Sopenharmony_ci        return false;
21599552fe9Sopenharmony_ci    }
21699552fe9Sopenharmony_ci    fullPath = tmpPath;
21799552fe9Sopenharmony_ci    return true;
21899552fe9Sopenharmony_ci}
21999552fe9Sopenharmony_ci
22099552fe9Sopenharmony_cistd::vector<std::string> JsonUtils::SplitVersion(const std::string& versionStr, char versionDelim)
22199552fe9Sopenharmony_ci{
22299552fe9Sopenharmony_ci    std::vector<std::string> tokens;
22399552fe9Sopenharmony_ci    std::stringstream ss(versionStr);
22499552fe9Sopenharmony_ci    std::string token;
22599552fe9Sopenharmony_ci    while (std::getline(ss, token, versionDelim)) {
22699552fe9Sopenharmony_ci        if (!token.empty()) {
22799552fe9Sopenharmony_ci            tokens.push_back(token);
22899552fe9Sopenharmony_ci        }
22999552fe9Sopenharmony_ci    }
23099552fe9Sopenharmony_ci    return tokens;
23199552fe9Sopenharmony_ci}
23299552fe9Sopenharmony_ci}  // namespace DevStandbyMgr
23399552fe9Sopenharmony_ci}  // namespace OHOS