1686862fbSopenharmony_ci/*
2686862fbSopenharmony_ci * Copyright (c) 2024 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_DISTRIBUTED_JSON_UTIL_H
17686862fbSopenharmony_ci#define OHOS_DISTRIBUTED_JSON_UTIL_H
18686862fbSopenharmony_ci
19686862fbSopenharmony_ci#include <string>
20686862fbSopenharmony_ci
21686862fbSopenharmony_ci#include "appexecfwk_errors.h"
22686862fbSopenharmony_ci#include "bundle_constants.h"
23686862fbSopenharmony_ci#include "hilog_wrapper.h"
24686862fbSopenharmony_ci#include "json_serializer.h"
25686862fbSopenharmony_ci
26686862fbSopenharmony_cinamespace OHOS {
27686862fbSopenharmony_cinamespace DistributedSchedule {
28686862fbSopenharmony_cienum class JsonType {
29686862fbSopenharmony_ci    NULLABLE,
30686862fbSopenharmony_ci    BOOLEAN,
31686862fbSopenharmony_ci    NUMBER,
32686862fbSopenharmony_ci    OBJECT,
33686862fbSopenharmony_ci    ARRAY,
34686862fbSopenharmony_ci    STRING,
35686862fbSopenharmony_ci};
36686862fbSopenharmony_ci
37686862fbSopenharmony_cienum class ArrayType {
38686862fbSopenharmony_ci    NUMBER,
39686862fbSopenharmony_ci    OBJECT,
40686862fbSopenharmony_ci    STRING,
41686862fbSopenharmony_ci    NOT_ARRAY,
42686862fbSopenharmony_ci};
43686862fbSopenharmony_ci
44686862fbSopenharmony_citemplate<typename T, typename dataType>
45686862fbSopenharmony_civoid CheckArrayType(
46686862fbSopenharmony_ci    const nlohmann::json &jsonObject, const std::string &key, dataType &data, ArrayType arrayType, int32_t &parseResult)
47686862fbSopenharmony_ci{
48686862fbSopenharmony_ci    auto arrays = jsonObject.at(key);
49686862fbSopenharmony_ci    if (arrays.empty()) {
50686862fbSopenharmony_ci        return;
51686862fbSopenharmony_ci    }
52686862fbSopenharmony_ci    if (arrays.size() > AppExecFwk::Constants::MAX_JSON_ARRAY_LENGTH) {
53686862fbSopenharmony_ci        parseResult = ERR_APPEXECFWK_PARSE_PROFILE_PROP_SIZE_CHECK_ERROR;
54686862fbSopenharmony_ci        return;
55686862fbSopenharmony_ci    }
56686862fbSopenharmony_ci    switch (arrayType) {
57686862fbSopenharmony_ci        case ArrayType::STRING:
58686862fbSopenharmony_ci            for (const auto &array : arrays) {
59686862fbSopenharmony_ci                if (!array.is_string()) {
60686862fbSopenharmony_ci                    parseResult = ERR_APPEXECFWK_PARSE_PROFILE_PROP_TYPE_ERROR;
61686862fbSopenharmony_ci                }
62686862fbSopenharmony_ci            }
63686862fbSopenharmony_ci            if (parseResult == ERR_OK) {
64686862fbSopenharmony_ci                data = jsonObject.at(key).get<T>();
65686862fbSopenharmony_ci            }
66686862fbSopenharmony_ci            break;
67686862fbSopenharmony_ci        case ArrayType::OBJECT:
68686862fbSopenharmony_ci            for (const auto &array : arrays) {
69686862fbSopenharmony_ci                if (!array.is_object()) {
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                    parseResult = ERR_APPEXECFWK_PARSE_PROFILE_PROP_TYPE_ERROR;
82686862fbSopenharmony_ci                }
83686862fbSopenharmony_ci            }
84686862fbSopenharmony_ci            if (parseResult == ERR_OK) {
85686862fbSopenharmony_ci                data = jsonObject.at(key).get<T>();
86686862fbSopenharmony_ci            }
87686862fbSopenharmony_ci            break;
88686862fbSopenharmony_ci        case ArrayType::NOT_ARRAY:
89686862fbSopenharmony_ci            HILOG_DEBUG("array %{public}s is not string type", key.c_str());
90686862fbSopenharmony_ci            break;
91686862fbSopenharmony_ci        default:
92686862fbSopenharmony_ci            HILOG_DEBUG("array %{public}s type error", key.c_str());
93686862fbSopenharmony_ci            break;
94686862fbSopenharmony_ci    }
95686862fbSopenharmony_ci}
96686862fbSopenharmony_ci
97686862fbSopenharmony_citemplate<typename T, typename dataType>
98686862fbSopenharmony_civoid GetValueIfFindKey(const nlohmann::json &jsonObject, const nlohmann::detail::iter_impl<const nlohmann::json> &end,
99686862fbSopenharmony_ci    const std::string &key, dataType &data, JsonType jsonType, bool isNecessary, int32_t &parseResult,
100686862fbSopenharmony_ci    ArrayType arrayType)
101686862fbSopenharmony_ci{
102686862fbSopenharmony_ci    if (parseResult) {
103686862fbSopenharmony_ci        return;
104686862fbSopenharmony_ci    }
105686862fbSopenharmony_ci    if (jsonObject.find(key) != end) {
106686862fbSopenharmony_ci        switch (jsonType) {
107686862fbSopenharmony_ci            case JsonType::BOOLEAN:
108686862fbSopenharmony_ci                if (!jsonObject.at(key).is_boolean()) {
109686862fbSopenharmony_ci                    HILOG_DEBUG("type is error %{public}s is not boolean", key.c_str());
110686862fbSopenharmony_ci                    parseResult = ERR_APPEXECFWK_PARSE_PROFILE_PROP_TYPE_ERROR;
111686862fbSopenharmony_ci                    break;
112686862fbSopenharmony_ci                }
113686862fbSopenharmony_ci                data = jsonObject.at(key).get<T>();
114686862fbSopenharmony_ci                break;
115686862fbSopenharmony_ci            case JsonType::NUMBER:
116686862fbSopenharmony_ci                if (!jsonObject.at(key).is_number()) {
117686862fbSopenharmony_ci                    HILOG_DEBUG("type is error %{public}s is not number", key.c_str());
118686862fbSopenharmony_ci                    parseResult = ERR_APPEXECFWK_PARSE_PROFILE_PROP_TYPE_ERROR;
119686862fbSopenharmony_ci                    break;
120686862fbSopenharmony_ci                }
121686862fbSopenharmony_ci                data = jsonObject.at(key).get<T>();
122686862fbSopenharmony_ci                break;
123686862fbSopenharmony_ci            case JsonType::OBJECT:
124686862fbSopenharmony_ci                if (!jsonObject.at(key).is_object()) {
125686862fbSopenharmony_ci                    HILOG_DEBUG("type is error %{public}s is not object", key.c_str());
126686862fbSopenharmony_ci                    parseResult = ERR_APPEXECFWK_PARSE_PROFILE_PROP_TYPE_ERROR;
127686862fbSopenharmony_ci                    break;
128686862fbSopenharmony_ci                }
129686862fbSopenharmony_ci                data = jsonObject.at(key).get<T>();
130686862fbSopenharmony_ci                break;
131686862fbSopenharmony_ci            case JsonType::ARRAY:
132686862fbSopenharmony_ci                if (!jsonObject.at(key).is_array()) {
133686862fbSopenharmony_ci                    HILOG_DEBUG("type is error %{public}s is not array", key.c_str());
134686862fbSopenharmony_ci                    parseResult = ERR_APPEXECFWK_PARSE_PROFILE_PROP_TYPE_ERROR;
135686862fbSopenharmony_ci                    break;
136686862fbSopenharmony_ci                }
137686862fbSopenharmony_ci                CheckArrayType<T>(jsonObject, key, data, arrayType, parseResult);
138686862fbSopenharmony_ci                break;
139686862fbSopenharmony_ci            case JsonType::STRING:
140686862fbSopenharmony_ci                if (!jsonObject.at(key).is_string()) {
141686862fbSopenharmony_ci                    HILOG_DEBUG("type is error %{public}s is not string", key.c_str());
142686862fbSopenharmony_ci                    parseResult = ERR_APPEXECFWK_PARSE_PROFILE_PROP_TYPE_ERROR;
143686862fbSopenharmony_ci                    break;
144686862fbSopenharmony_ci                }
145686862fbSopenharmony_ci                data = jsonObject.at(key).get<T>();
146686862fbSopenharmony_ci                if (jsonObject.at(key).get<std::string>().length() > AppExecFwk::Constants::MAX_JSON_ELEMENT_LENGTH) {
147686862fbSopenharmony_ci                    parseResult = ERR_APPEXECFWK_PARSE_PROFILE_PROP_SIZE_CHECK_ERROR;
148686862fbSopenharmony_ci                }
149686862fbSopenharmony_ci                break;
150686862fbSopenharmony_ci            case JsonType::NULLABLE:
151686862fbSopenharmony_ci                HILOG_DEBUG("type is error %{public}s is nullable", key.c_str());
152686862fbSopenharmony_ci                break;
153686862fbSopenharmony_ci            default:
154686862fbSopenharmony_ci                HILOG_DEBUG("type is error %{public}s is not jsonType", key.c_str());
155686862fbSopenharmony_ci                parseResult = ERR_APPEXECFWK_PARSE_PROFILE_PROP_TYPE_ERROR;
156686862fbSopenharmony_ci        }
157686862fbSopenharmony_ci        return;
158686862fbSopenharmony_ci    }
159686862fbSopenharmony_ci    if (isNecessary) {
160686862fbSopenharmony_ci        HILOG_DEBUG("profile prop %{public}s is mission", key.c_str());
161686862fbSopenharmony_ci        parseResult = ERR_APPEXECFWK_PARSE_PROFILE_MISSING_PROP;
162686862fbSopenharmony_ci    }
163686862fbSopenharmony_ci}
164686862fbSopenharmony_ci
165686862fbSopenharmony_citemplate<typename T>
166686862fbSopenharmony_ciconst std::string GetJsonStrFromInfo(T &t)
167686862fbSopenharmony_ci{
168686862fbSopenharmony_ci    nlohmann::json json = t;
169686862fbSopenharmony_ci    return json.dump();
170686862fbSopenharmony_ci}
171686862fbSopenharmony_ci
172686862fbSopenharmony_citemplate<typename T>
173686862fbSopenharmony_cibool ParseInfoFromJsonStr(const char *data, T &t)
174686862fbSopenharmony_ci{
175686862fbSopenharmony_ci    if (data == nullptr) {
176686862fbSopenharmony_ci        HILOG_DEBUG("%{public}s failed due to data is nullptr", __func__);
177686862fbSopenharmony_ci        return false;
178686862fbSopenharmony_ci    }
179686862fbSopenharmony_ci
180686862fbSopenharmony_ci    nlohmann::json jsonObject = nlohmann::json::parse(data, nullptr, false);
181686862fbSopenharmony_ci    if (jsonObject.is_discarded()) {
182686862fbSopenharmony_ci        HILOG_DEBUG("%{public}s failed due to data is discarded", __func__);
183686862fbSopenharmony_ci        return false;
184686862fbSopenharmony_ci    }
185686862fbSopenharmony_ci
186686862fbSopenharmony_ci    t = jsonObject.get<T>();
187686862fbSopenharmony_ci    return true;
188686862fbSopenharmony_ci}
189686862fbSopenharmony_ci} // namespace DistributedSchedule
190686862fbSopenharmony_ci} // namespace OHOS
191686862fbSopenharmony_ci#endif // OHOS_DISTRIBUTED_JSON_UTIL_H