1686862fbSopenharmony_ci/*
2686862fbSopenharmony_ci * Copyright (c) 2023 Huawei Device Co., Ltd.
3686862fbSopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License");
4686862fbSopenharmony_ci * you may not use this file except in compliance with the License.
5686862fbSopenharmony_ci * You may obtain a copy of the License at
6686862fbSopenharmony_ci *
7686862fbSopenharmony_ci *     http://www.apache.org/licenses/LICENSE-2.0
8686862fbSopenharmony_ci *
9686862fbSopenharmony_ci * Unless required by applicable law or agreed to in writing, software
10686862fbSopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS,
11686862fbSopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12686862fbSopenharmony_ci * See the License for the specific language governing permissions and
13686862fbSopenharmony_ci * limitations under the License.
14686862fbSopenharmony_ci */
15686862fbSopenharmony_ci
16686862fbSopenharmony_ci#ifndef OHOS_DMSFWK_JSON_UTIL_H
17686862fbSopenharmony_ci#define OHOS_DMSFWK_JSON_UTIL_H
18686862fbSopenharmony_ci
19686862fbSopenharmony_ci#include <string>
20686862fbSopenharmony_ci
21686862fbSopenharmony_ci#include "dtbschedmgr_log.h"
22686862fbSopenharmony_ci
23686862fbSopenharmony_cinamespace OHOS {
24686862fbSopenharmony_cinamespace DistributedSchedule {
25686862fbSopenharmony_cinamespace {
26686862fbSopenharmony_ciconst std::string TAG = "jsonUtil";
27686862fbSopenharmony_ci}
28686862fbSopenharmony_ci
29686862fbSopenharmony_cienum class JsonType {
30686862fbSopenharmony_ci    NULLABLE,
31686862fbSopenharmony_ci    BOOLEAN,
32686862fbSopenharmony_ci    NUMBER,
33686862fbSopenharmony_ci    OBJECT,
34686862fbSopenharmony_ci    ARRAY,
35686862fbSopenharmony_ci    STRING,
36686862fbSopenharmony_ci};
37686862fbSopenharmony_ci
38686862fbSopenharmony_cienum class ArrayType {
39686862fbSopenharmony_ci    NUMBER,
40686862fbSopenharmony_ci    OBJECT,
41686862fbSopenharmony_ci    STRING,
42686862fbSopenharmony_ci    NOT_ARRAY,
43686862fbSopenharmony_ci};
44686862fbSopenharmony_ci
45686862fbSopenharmony_citemplate<typename T, typename dataType>
46686862fbSopenharmony_civoid CheckArrayType(const nlohmann::json &jsonObject, const std::string &key,
47686862fbSopenharmony_ci    dataType &data, ArrayType arrayType, int32_t &parseResult)
48686862fbSopenharmony_ci{
49686862fbSopenharmony_ci    auto arrays = jsonObject.at(key);
50686862fbSopenharmony_ci    if (arrays.empty()) {
51686862fbSopenharmony_ci        HILOGD("array is empty");
52686862fbSopenharmony_ci        return;
53686862fbSopenharmony_ci    }
54686862fbSopenharmony_ci    switch (arrayType) {
55686862fbSopenharmony_ci        case ArrayType::STRING:
56686862fbSopenharmony_ci            for (const auto &array : arrays) {
57686862fbSopenharmony_ci                if (!array.is_string()) {
58686862fbSopenharmony_ci                    HILOGE("array %{public}s is not string type", key.c_str());
59686862fbSopenharmony_ci                    parseResult = ERR_APPEXECFWK_PARSE_PROFILE_PROP_TYPE_ERROR;
60686862fbSopenharmony_ci                }
61686862fbSopenharmony_ci            }
62686862fbSopenharmony_ci            if (parseResult == ERR_OK) {
63686862fbSopenharmony_ci                data = jsonObject.at(key).get<T>();
64686862fbSopenharmony_ci            }
65686862fbSopenharmony_ci            break;
66686862fbSopenharmony_ci        case ArrayType::OBJECT:
67686862fbSopenharmony_ci            for (const auto &array : arrays) {
68686862fbSopenharmony_ci                if (!array.is_object()) {
69686862fbSopenharmony_ci                    HILOGE("array %{public}s is not object type", key.c_str());
70686862fbSopenharmony_ci                    parseResult = ERR_APPEXECFWK_PARSE_PROFILE_PROP_TYPE_ERROR;
71686862fbSopenharmony_ci                    break;
72686862fbSopenharmony_ci                }
73686862fbSopenharmony_ci            }
74686862fbSopenharmony_ci            if (parseResult == ERR_OK) {
75686862fbSopenharmony_ci                data = jsonObject.at(key).get<T>();
76686862fbSopenharmony_ci            }
77686862fbSopenharmony_ci            break;
78686862fbSopenharmony_ci        case ArrayType::NUMBER:
79686862fbSopenharmony_ci            for (const auto &array : arrays) {
80686862fbSopenharmony_ci                if (!array.is_number()) {
81686862fbSopenharmony_ci                    HILOGE("array %{public}s is not number type", key.c_str());
82686862fbSopenharmony_ci                    parseResult = ERR_APPEXECFWK_PARSE_PROFILE_PROP_TYPE_ERROR;
83686862fbSopenharmony_ci                }
84686862fbSopenharmony_ci            }
85686862fbSopenharmony_ci            if (parseResult == ERR_OK) {
86686862fbSopenharmony_ci                data = jsonObject.at(key).get<T>();
87686862fbSopenharmony_ci            }
88686862fbSopenharmony_ci            break;
89686862fbSopenharmony_ci        case ArrayType::NOT_ARRAY:
90686862fbSopenharmony_ci            HILOGE("array %{public}s is not array type", key.c_str());
91686862fbSopenharmony_ci            break;
92686862fbSopenharmony_ci        default:
93686862fbSopenharmony_ci            HILOGE("array %{public}s type error", key.c_str());
94686862fbSopenharmony_ci            break;
95686862fbSopenharmony_ci    }
96686862fbSopenharmony_ci}
97686862fbSopenharmony_ci
98686862fbSopenharmony_citemplate<typename T, typename dataType>
99686862fbSopenharmony_civoid GetValueIfFindKey(const nlohmann::json &jsonObject, const nlohmann::detail::iter_impl<const nlohmann::json> &end,
100686862fbSopenharmony_ci    const std::string &key, dataType &data, JsonType jsonType, bool isNecessary, int32_t &parseResult,
101686862fbSopenharmony_ci    ArrayType arrayType)
102686862fbSopenharmony_ci{
103686862fbSopenharmony_ci    if (parseResult) {
104686862fbSopenharmony_ci        return;
105686862fbSopenharmony_ci    }
106686862fbSopenharmony_ci    if (jsonObject.find(key) != end) {
107686862fbSopenharmony_ci        switch (jsonType) {
108686862fbSopenharmony_ci            case JsonType::BOOLEAN:
109686862fbSopenharmony_ci                if (!jsonObject.at(key).is_boolean()) {
110686862fbSopenharmony_ci                    HILOGE("type is error %{public}s is not boolean", key.c_str());
111686862fbSopenharmony_ci                    parseResult = ERR_APPEXECFWK_PARSE_PROFILE_PROP_TYPE_ERROR;
112686862fbSopenharmony_ci                    break;
113686862fbSopenharmony_ci                }
114686862fbSopenharmony_ci                data = jsonObject.at(key).get<T>();
115686862fbSopenharmony_ci                break;
116686862fbSopenharmony_ci            case JsonType::NUMBER:
117686862fbSopenharmony_ci                if (!jsonObject.at(key).is_number()) {
118686862fbSopenharmony_ci                    HILOGE("type is error %{public}s is not number", key.c_str());
119686862fbSopenharmony_ci                    parseResult = ERR_APPEXECFWK_PARSE_PROFILE_PROP_TYPE_ERROR;
120686862fbSopenharmony_ci                    break;
121686862fbSopenharmony_ci                }
122686862fbSopenharmony_ci                data = jsonObject.at(key).get<T>();
123686862fbSopenharmony_ci                break;
124686862fbSopenharmony_ci            case JsonType::OBJECT:
125686862fbSopenharmony_ci                if (!jsonObject.at(key).is_object()) {
126686862fbSopenharmony_ci                    HILOGE("type is error %{public}s is not object", key.c_str());
127686862fbSopenharmony_ci                    parseResult = ERR_APPEXECFWK_PARSE_PROFILE_PROP_TYPE_ERROR;
128686862fbSopenharmony_ci                    break;
129686862fbSopenharmony_ci                }
130686862fbSopenharmony_ci                data = jsonObject.at(key).get<T>();
131686862fbSopenharmony_ci                break;
132686862fbSopenharmony_ci            case JsonType::ARRAY:
133686862fbSopenharmony_ci                if (!jsonObject.at(key).is_array()) {
134686862fbSopenharmony_ci                    HILOGE("type is error %{public}s is not array", key.c_str());
135686862fbSopenharmony_ci                    parseResult = ERR_APPEXECFWK_PARSE_PROFILE_PROP_TYPE_ERROR;
136686862fbSopenharmony_ci                    break;
137686862fbSopenharmony_ci                }
138686862fbSopenharmony_ci                CheckArrayType<T>(jsonObject, key, data, arrayType, parseResult);
139686862fbSopenharmony_ci                break;
140686862fbSopenharmony_ci            case JsonType::STRING:
141686862fbSopenharmony_ci                if (!jsonObject.at(key).is_string()) {
142686862fbSopenharmony_ci                    HILOGE("type is error %{public}s is not string", key.c_str());
143686862fbSopenharmony_ci                    parseResult = ERR_APPEXECFWK_PARSE_PROFILE_PROP_TYPE_ERROR;
144686862fbSopenharmony_ci                    break;
145686862fbSopenharmony_ci                }
146686862fbSopenharmony_ci                data = jsonObject.at(key).get<T>();
147686862fbSopenharmony_ci                break;
148686862fbSopenharmony_ci            case JsonType::NULLABLE:
149686862fbSopenharmony_ci                HILOGE("type is error %{public}s is nullable", key.c_str());
150686862fbSopenharmony_ci                break;
151686862fbSopenharmony_ci            default:
152686862fbSopenharmony_ci                HILOGE("type is error %{public}s is not jsonType", key.c_str());
153686862fbSopenharmony_ci                parseResult = ERR_APPEXECFWK_PARSE_PROFILE_PROP_TYPE_ERROR;
154686862fbSopenharmony_ci        }
155686862fbSopenharmony_ci        return;
156686862fbSopenharmony_ci    }
157686862fbSopenharmony_ci    if (isNecessary) {
158686862fbSopenharmony_ci        HILOGE("profile prop %{public}s is mission", key.c_str());
159686862fbSopenharmony_ci        parseResult = ERR_APPEXECFWK_PARSE_PROFILE_MISSING_PROP;
160686862fbSopenharmony_ci    }
161686862fbSopenharmony_ci}
162686862fbSopenharmony_ci
163686862fbSopenharmony_citemplate<typename T>
164686862fbSopenharmony_ciconst std::string GetJsonStrFromInfo(T &t)
165686862fbSopenharmony_ci{
166686862fbSopenharmony_ci    nlohmann::json json = t;
167686862fbSopenharmony_ci    return json.dump();
168686862fbSopenharmony_ci}
169686862fbSopenharmony_ci
170686862fbSopenharmony_citemplate<typename T>
171686862fbSopenharmony_cibool ParseInfoFromJsonStr(const char *data, T &t)
172686862fbSopenharmony_ci{
173686862fbSopenharmony_ci    if (data == nullptr) {
174686862fbSopenharmony_ci        HILOGE("%{public}s failed due to data is nullptr", __func__);
175686862fbSopenharmony_ci        return false;
176686862fbSopenharmony_ci    }
177686862fbSopenharmony_ci
178686862fbSopenharmony_ci    nlohmann::json jsonObject = nlohmann::json::parse(data, nullptr, false);
179686862fbSopenharmony_ci    if (jsonObject.is_discarded()) {
180686862fbSopenharmony_ci        HILOGE("%{public}s failed due to data is discarded", __func__);
181686862fbSopenharmony_ci        return false;
182686862fbSopenharmony_ci    }
183686862fbSopenharmony_ci
184686862fbSopenharmony_ci    t = jsonObject.get<T>();
185686862fbSopenharmony_ci    return true;
186686862fbSopenharmony_ci}
187686862fbSopenharmony_ci}  // namespace DistributedSchedule
188686862fbSopenharmony_ci}  // namespace OHOS
189686862fbSopenharmony_ci#endif  // OHOS_DMSFWK_JSON_UTIL_H
190