1/* 2* Copyright (c) 2023 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 JSON_UTILS_H 17#define JSON_UTILS_H 18 19#include <algorithm> 20#include <functional> 21#include <string> 22 23#include "nlohmann/json.hpp" 24 25#include "update_define.h" 26 27namespace OHOS::UpdateEngine { 28enum class JsonParseError { 29 ERR_OK = 0, 30 COMMOM_ERROR, 31 MISSING_PROP, 32 TYPE_ERROR 33}; 34 35// 开发人员请使用该工具类封装的安全函数来获取json对象/数组,以及从json对象获取Value 36// 当前获取json对象/数组的封装使用的parse方法参数:string输入、无解析回调、解析失败不报异常 37class JsonUtils { 38public: 39 template <typename T> 40 static int32_t GetValueAndSetTo(const nlohmann::json &jsonObject, const std::string &key, T &value) 41 { 42 if (jsonObject.find(key) == jsonObject.end()) { 43 return CAST_INT(JsonParseError::MISSING_PROP); 44 } 45 if (!CheckType(jsonObject.at(key), value)) { 46 return CAST_INT(JsonParseError::TYPE_ERROR); 47 } 48 GetValue(jsonObject, key, value); 49 return CAST_INT(JsonParseError::ERR_OK); 50 } 51 52 static bool ParseAndGetJsonObject(const std::string &jsonStr, nlohmann::json &root) 53 { 54 root = nlohmann::json::parse(jsonStr, nullptr, false); 55 if (root.is_discarded() || !root.is_object()) { 56 return false; 57 } 58 return true; 59 } 60 61 static bool ParseAndGetJsonArray(const std::string &jsonStr, nlohmann::json &root) 62 { 63 root = nlohmann::json::parse(jsonStr, nullptr, false); 64 if (root.is_discarded() || !root.is_array()) { 65 return false; 66 } 67 return true; 68 } 69 70 static int32_t GetValueAndSetToArray(const nlohmann::json &jsonObject, const std::string &key, 71 nlohmann::json &value) 72 { 73 if (jsonObject.find(key) == jsonObject.end()) { 74 return CAST_INT(JsonParseError::MISSING_PROP); 75 } 76 if (!jsonObject.at(key).is_array()) { 77 return CAST_INT(JsonParseError::TYPE_ERROR); 78 } 79 jsonObject.at(key).get_to(value); 80 return CAST_INT(JsonParseError::ERR_OK); 81 } 82 83 static void SetJsonToVector(nlohmann::json &jsonObject, std::vector<std::string> &vector) 84 { 85 if (jsonObject.is_array()) { 86 for (nlohmann::json::iterator it = jsonObject.begin(); it != jsonObject.end(); ++it) { 87 if (!it.value().is_string()) { 88 continue; 89 } 90 vector.push_back(static_cast<std::string>(it.value())); 91 } 92 } 93 } 94 95 static void SetJsonToVector(const nlohmann::json &jsonObject, const std::string &key, 96 std::vector<std::string> &vector) 97 { 98 if (!IsArray(jsonObject, key)) { 99 return; 100 } 101 nlohmann::json jsonArray = jsonObject.at(key); 102 SetJsonToVector(jsonArray, vector); 103 } 104 105 static bool IsArray(const nlohmann::json &jsonObject, const std::string &key) 106 { 107 if (jsonObject.find(key) == jsonObject.end()) { 108 return false; 109 } 110 return jsonObject.at(key).is_array(); 111 } 112 113 template <typename T> static std::string StructToJsonStr(const T &value) 114 { 115 nlohmann::json jsonObj(value); 116 return jsonObj.dump(); 117 } 118 119 template <typename T> static int32_t JsonStrToStruct(const std::string &jsonStr, T &value) 120 { 121 if (jsonStr.empty()) { 122 return CAST_INT(JsonParseError::COMMOM_ERROR); 123 } 124 nlohmann::json jsonObj = nlohmann::json::parse(jsonStr, nullptr, false); 125 if (!jsonObj.is_discarded() && CheckType(jsonObj, value)) { 126 value = jsonObj.get<T>(); 127 return CAST_INT(JsonParseError::ERR_OK); 128 } 129 return CAST_INT(JsonParseError::TYPE_ERROR); 130 } 131 132private: 133 static bool CheckType(const nlohmann::json &jsonObject, std::string &value) 134 { 135 return jsonObject.is_string(); 136 } 137 138 static bool CheckType(const nlohmann::json &jsonObject, int32_t &value) 139 { 140 return jsonObject.is_number(); 141 } 142 143 static bool CheckType(const nlohmann::json &jsonObject, uint32_t &value) 144 { 145 return jsonObject.is_number(); 146 } 147 148 static bool CheckType(const nlohmann::json &jsonObject, uint64_t &value) 149 { 150 return jsonObject.is_number(); 151 } 152 153 static bool CheckType(const nlohmann::json &jsonObject, int64_t &value) 154 { 155 return jsonObject.is_number(); 156 } 157 158 static bool CheckType(const nlohmann::json &jsonObject, double &value) 159 { 160 return jsonObject.is_number(); 161 } 162 163 static bool CheckType(const nlohmann::json &jsonObject, bool &value) 164 { 165 return jsonObject.is_boolean(); 166 } 167 168 template <typename T> static bool CheckType(const nlohmann::json &jsonObject, T &value) 169 { 170 return jsonObject.is_object(); 171 } 172 173 template <typename T> static bool CheckType(const nlohmann::json &jsonObject, std::vector<T> &value) 174 { 175 return jsonObject.is_array(); 176 } 177 178 template <typename T> static void GetValue(const nlohmann::json &jsonObject, const std::string &key, T &value) 179 { 180 jsonObject.at(key).get_to(value); 181 } 182 183 static void GetValue(const nlohmann::json &jsonObject, const std::string &key, std::vector<std::string> &value) 184 { 185 if (!IsArray(jsonObject, key)) { 186 return; 187 } 188 nlohmann::json jsonArray = jsonObject.at(key); 189 for (nlohmann::json::iterator it = jsonArray.begin(); it != jsonArray.end(); ++it) { 190 if (!it.value().is_string()) { 191 continue; 192 } 193 value.push_back(static_cast<std::string>(it.value())); 194 } 195 } 196}; 197} // namespace OHOS::UpdateEngine 198#endif // JSON_UTILS_H