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 UPDATESERVICE_JSON_UTILS_H 17 #define UPDATESERVICE_JSON_UTILS_H 18 19 #include <algorithm> 20 #include <functional> 21 #include <string> 22 #include <unistd.h> 23 24 #include "cJSON.h" 25 #include "update_define.h" 26 27 namespace OHOS::UpdateService { 28 enum 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输入、无解析回调、解析失败不报异常 37 class UpdateServiceJsonUtils { 38 public: GetValueAndSetTo(cJSON * jsonObject,const std::string & key,T & value)39 template <typename T> static int32_t GetValueAndSetTo(cJSON *jsonObject, const std::string &key, T &value) 40 { 41 if (!jsonObject || key.empty()) { 42 return CAST_INT(JsonParseError::MISSING_PROP); 43 } 44 45 cJSON *item = cJSON_GetObjectItemCaseSensitive(jsonObject, key.c_str()); 46 if (item == nullptr) { 47 return CAST_INT(JsonParseError::MISSING_PROP); 48 } 49 50 if (!CheckTypeAndAsign(item, value)) { 51 return CAST_INT(JsonParseError::TYPE_ERROR); 52 } 53 return CAST_INT(JsonParseError::ERR_OK); 54 } 55 ParseAndGetJsonObject(const std::string & jsonStr)56 static cJSON *ParseAndGetJsonObject(const std::string &jsonStr) 57 { 58 cJSON *object = cJSON_Parse(jsonStr.c_str()); 59 if (object == nullptr) { 60 return nullptr; 61 } 62 63 if (!cJSON_IsObject(object)) { 64 cJSON_Delete(object); 65 return nullptr; 66 } 67 68 return object; 69 } 70 ParseJson(const std::string & jsonStr)71 static std::shared_ptr<cJSON> ParseJson(const std::string &jsonStr) 72 { 73 cJSON *root = cJSON_Parse(jsonStr.c_str()); 74 if (root == nullptr) { 75 return nullptr; 76 } 77 78 return std::shared_ptr<cJSON>(root, [](cJSON *r) { cJSON_Delete(r); }); 79 } 80 81 private: 82 IsInteger(double d)83 static bool IsInteger(double d) 84 { 85 return std::floor(d) == d; 86 } 87 88 // 判断int32_t, int64_t, uint32_t, uint64_t 是否合法整数 CheckInteger(cJSON * jsonObj,T & value)89 template <typename T> static bool CheckInteger(cJSON *jsonObj, T &value) 90 { 91 if (!cJSON_IsNumber(jsonObj)) { 92 return false; 93 } 94 95 double objValue = jsonObj->valuedouble; 96 if (!IsInteger(objValue)) { 97 return false; 98 } 99 100 if (std::is_same_v<T, int32_t>) { 101 if (objValue < std::numeric_limits<int32_t>::min() || objValue > std::numeric_limits<int32_t>::max()) { 102 return false; 103 } 104 } 105 106 if (std::is_same_v<T, int64_t>) { 107 if (objValue < std::numeric_limits<int64_t>::min() || objValue > std::numeric_limits<int64_t>::max()) { 108 return false; 109 } 110 } 111 112 if (std::is_same_v<T, uint32_t>) { 113 if (objValue < 0 || objValue > std::numeric_limits<uint32_t>::max()) { 114 return false; 115 } 116 } 117 118 if (std::is_same_v<T, uint64_t>) { 119 if (objValue < 0 || objValue > std::numeric_limits<uint64_t>::max()) { 120 return false; 121 } 122 } 123 value = objValue; 124 return true; 125 } 126 127 // 检查基本类型 CheckTypeAndAsign(cJSON * jsonObject,T & value)128 template <typename T> static bool CheckTypeAndAsign(cJSON *jsonObject, T &value) 129 { 130 if constexpr (std::is_same_v<T, std::string>) { 131 if (cJSON_IsString(jsonObject)) { 132 value = jsonObject->valuestring; 133 return true; 134 } 135 return false; 136 } 137 138 if constexpr (std::is_same_v<T, bool>) { 139 if (jsonObject->type != cJSON_True && jsonObject->type != cJSON_False) { 140 return false; 141 } 142 value = cJSON_IsTrue(jsonObject) ? true : false; 143 return true; 144 } 145 146 if constexpr (std::is_same_v<T, int32_t> || std::is_same_v<T, int64_t> || 147 std::is_same_v<T, uint32_t> || std::is_same_v<T, uint64_t>) { 148 return CheckInteger(jsonObject, value); 149 } 150 151 if constexpr (std::is_same_v<T, double>) { 152 if (!cJSON_IsNumber(jsonObject)) { 153 return false; 154 } 155 double dbValue = jsonObject->valuedouble; 156 if (!std::isfinite(dbValue)) { 157 return false; 158 } 159 value = dbValue; 160 return true; 161 } 162 return false; 163 } 164 }; 165 } // namespace OHOS::UpdateService 166 #endif // UPDATESERVICE_JSON_UTILS_H 167