1 /*
2 * Copyright (C) 2025 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16 #ifndef OS_ACCOUNT_JSON_UTILS_H
17 #define OS_ACCOUNT_JSON_UTILS_H
18
19 #include <map>
20 #include <memory>
21 #include <vector>
22 #include <string>
23 #include <set>
24 #include <functional>
25 #include "cJSON.h"
26
27 namespace OHOS {
28 namespace AccountSA {
29 typedef cJSON CJson;
30 typedef std::unique_ptr<CJson, std::function<void(CJson *ptr)>> CJsonUnique;
31
32 /* No need to call FreeJson to free the returned pointer when it's no longer in use. */
33 CJsonUnique CreateJsonFromString(const std::string &jsonStr);
34 CJsonUnique CreateJsonNull(void);
35 CJsonUnique CreateJson(void);
36 CJsonUnique CreateJsonArray(void);
37 CJsonUnique CreateJsonString(const char *string);
38
39 int DeleteItemFromJson(CJson *jsonObj, const std::string &key);
40 int DeleteItemFromJson(CJsonUnique &jsonObj, const std::string &key);
41
42 /* No need to call FreeJsonString to free the returned pointer when it's no longer in use. */
43 std::string PackJsonToString(const CJsonUnique &jsonObj);
44 std::string PackJsonToString(const CJson *jsonObj);
45
46 int32_t GetItemNum(const CJson *jsonObj);
47 int32_t GetItemNum(const CJsonUnique &jsonObj);
48
49 /*
50 * Can't release the returned pointer, otherwise, an exception may occur.
51 * It refers to the parent object(param--jsonObj)'s memory.
52 * It will be recycled along with jsonObj when jsonObj is released.
53 */
54 bool GetObjFromJson(const CJson *jsonObj, const std::string &key, CJson **value);
55 CJson *GetObjFromJson(const CJson *jsonObj, const std::string &key);
56 CJson *GetObjFromJson(const CJsonUnique &jsonObj, const std::string &key);
57 CJson *GetItemFromJson(const CJson *const object, const std::string &key);
58 CJson *GetItemFromJson(CJsonUnique &object, const std::string &key);
59 CJson *GetItemFromArray(const CJson *jsonArr, int32_t index);
60 CJson *GetItemFromArray(const CJsonUnique &jsonArr, int32_t index);
61
62 // common
63 bool IsKeyExist(const CJson *json_obj, const std::string &key);
64 bool IsKeyExist(const CJsonUnique &json_obj, const std::string &key);
65 bool IsStructured(CJson *jsonObj);
66 bool IsStructured(const CJsonUnique &jsonObj);
67 bool IsArray(const CJson *item);
68 bool IsArray(const CJsonUnique &item);
69 bool IsBool(const CJson *item);
70 bool IsBool(const CJsonUnique &item);
71 bool IsNumber(const CJson *item);
72 bool IsNumber(const CJsonUnique &item);
73 bool IsString(const CJson *item);
74 bool IsString(const CJsonUnique &item);
75 bool IsObject(const CJson *item);
76 bool IsObject(const CJsonUnique &item);
77 bool IsInvalid(const CJson *item);
78 bool IsInvalid(const CJsonUnique &item);
79
80 // bool
81 bool GetBoolFromJson(const CJsonUnique &jsonObj, const std::string &key, bool &value);
82 bool GetBoolFromJson(const CJson *jsonObj, const std::string &key, bool &value);
83 bool GetBoolFromJson(const CJsonUnique &jsonObj, const std::string &key);
84 bool GetBoolFromJson(const CJson *jsonObj, const std::string &key);
85 bool AddBoolToJson(CJson *jsonObj, const std::string &key, const bool value);
86 bool AddBoolToJson(CJsonUnique &jsonObj, const std::string &key, const bool value);
87
88 // int32
89 bool GetIntFromJson(const CJson *jsonObj, const std::string &key, int32_t &value);
90 bool AddIntToJson(CJson *jsonObj, const std::string &key, const int value);
91 bool AddIntToJson(CJsonUnique &jsonObj, const std::string &key, const int value);
92
93 // int64
94 bool GetInt64FromJson(const CJson *jsonObj, const std::string &key, int64_t &value);
95 bool AddInt64ToJson(CJson *jsonObj, const std::string &key, int64_t value);
96 bool AddInt64ToJson(CJsonUnique &jsonObj, const std::string &key, int64_t value);
97
98 // uint64
99 bool GetUint64FromJson(const CJson *jsonObj, const std::string &key, uint64_t &value);
100 bool AddUint64ToJson(CJson *jsonObj, const std::string &key, uint64_t value);
101 bool AddUint64ToJson(CJsonUnique &jsonObj, const std::string &key, uint64_t value);
102
103 // double
104 double GetJsonNumberValue(const CJsonUnique &item);
105 double GetJsonNumberValue(cJSON *item);
106
107 // string
108 bool GetStringFromJson(const CJson *jsonObj, const std::string &key, std::string &value);
109 std::string GetStringFromJson(const CJson *jsonObj, const std::string &key);
110 std::string GetStringFromJson(const CJsonUnique &jsonObj, const std::string &key);
111 bool AddStringToJson(CJson *jsonObj, const std::string &key, const std::string &value);
112 bool AddStringToJson(CJsonUnique &jsonObj, const std::string &key, const std::string &value);
113 bool AddStringToArray(CJson *jsonArr, const char *string);
114 bool AddStringToArray(CJsonUnique &jsonArr, const char *string);
115
116 CJson *GetJsonArrayFromJson(const CJson *jsonObj, const std::string &key);
117
118 // string vector
119 bool GetVectorStringFromJson(const CJson *jsonObj, const std::string &key, std::vector<std::string> &value);
120 std::vector<std::string> GetVectorStringFromJson(const CJson *jsonObj, const std::string &key);
121 std::vector<std::string> GetVectorStringFromJson(const CJsonUnique &jsonObj, const std::string &key);
122 bool AddVectorStringToJson(CJson *jsonObj, const std::string &key, const std::vector<std::string> &vec);
123 bool AddVectorStringToJson(CJsonUnique &jsonObj, const std::string &key, const std::vector<std::string> &vec);
124
125 // uint8 vector
126 std::vector<uint8_t> GetVectorUint8FromJson(const CJson *jsonObj, const std::string &key);
127 std::vector<uint8_t> GetVectorUint8FromJson(const CJsonUnique &jsonObj, const std::string &key);
128 bool AddVectorUint8ToJson(CJsonUnique &jsonObj, const std::string &key, std::vector<uint8_t> arr);
129 bool AddVectorUint8ToJson(CJson *jsonObj, const std::string &key, std::vector<uint8_t> arr);
130
131 // map
132 std::map<std::string, std::string> PackJsonToMap(const CJson *jsonObj);
133 std::map<std::string, std::string> PackJsonToMap(const CJsonUnique &jsonObj);
134 CJsonUnique CreateJsonFromMap(const std::map<std::string, std::string> &mapData);
135
136 // set
137 bool GetSetStringFromJson(const CJsonUnique &jsonObj, const std::string &key, std::set<std::string> &setData);
138 bool GetSetStringFromJson(const CJson *jsonObj, const std::string &key, std::set<std::string> &setData);
139 bool AddSetStringToJson(CJsonUnique &jsonObj, const std::string &key, const std::set<std::string> &setData);
140
141 // add obj
142 bool AddObjToJson(CJson *jsonObj, const std::string &key, const CJson *childObj);
143 bool AddObjToJson(CJsonUnique &jsonObj, const std::string &key, CJsonUnique &childObj);
144 bool AddObjToArray(CJsonUnique &jsonArr, CJsonUnique &item);
145
146 template <typename>
147 constexpr bool dependent_false = false;
148
149 template <typename T, typename dataType>
GetDataByType(const CJson * jsonObject,const std::string & key,dataType & data)150 bool GetDataByType(const CJson *jsonObject, const std::string &key, dataType &data)
151 {
152 static_assert(std::is_same_v<T, int> || std::is_same_v<T, int32_t> || std::is_same_v<T, uint32_t> ||
153 std::is_same_v<T, int64_t> || std::is_same_v<T, uint64_t> || std::is_same_v<T, bool> ||
154 std::is_same_v<T, std::string> || std::is_same_v<T, cJSON *> || std::is_enum_v<T> ||
155 std::is_same_v<T, std::vector<std::string>> || std::is_same_v<T, std::set<std::string>>,
156 "Unsupported type for GetDataByType");
157
158 if constexpr (std::is_same_v<T, int> || std::is_same_v<T, int32_t>) {
159 return GetIntFromJson(jsonObject, key, data);
160 } else if constexpr (std::is_same_v<T, int64_t>) {
161 return GetInt64FromJson(jsonObject, key, data);
162 } else if constexpr (std::is_same_v<T, uint64_t>) {
163 return GetUint64FromJson(jsonObject, key, data);
164 } else if constexpr (std::is_same_v<T, bool>) {
165 return GetBoolFromJson(jsonObject, key, data);
166 } else if constexpr (std::is_same_v<T, std::string>) {
167 return GetStringFromJson(jsonObject, key, data);
168 } else if constexpr (std::is_same_v<T, cJSON *>) {
169 return GetObjFromJson(jsonObject, key, &data);
170 } else if constexpr (std::is_same_v<T, std::vector<std::string>>) {
171 return GetVectorStringFromJson(jsonObject, key, data);
172 } else if constexpr (std::is_same_v<T, std::set<std::string>>) {
173 return GetSetStringFromJson(jsonObject, key, data);
174 } else if constexpr (std::is_enum_v<T> || std::is_same_v<T, uint32_t>) {
175 int value = 0;
176 if (!GetIntFromJson(jsonObject, key, value)) {
177 return false;
178 }
179 data = static_cast<dataType>(value);
180 return true;
181 } else {
182 static_assert(dependent_false<T>, "Non-exhaustive handling of types");
183 }
184 }
185
186 template <typename T, typename dataType>
GetDataByType(const CJsonUnique & jsonObject,const std::string & key,dataType & data)187 bool GetDataByType(const CJsonUnique &jsonObject, const std::string &key, dataType &data)
188 {
189 return GetDataByType<T, dataType>(jsonObject.get(), key, data);
190 }
191 } // namespace AccountSA
192 } // namespace OHOS
193 #endif // OS_ACCOUNT_JSON_UTILS_H
194