1 /* 2 * Copyright (c) 2024 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 INPUT_METHOD_SERIALIZABLE_H 17 #define INPUT_METHOD_SERIALIZABLE_H 18 #include <string> 19 #include <unordered_set> 20 21 #include "cJSON.h" 22 #include "global.h" 23 namespace OHOS { 24 namespace MiscServices { 25 #ifndef GET_NAME 26 #define GET_NAME(value) #value 27 #endif 28 struct Serializable { 29 public: ~SerializableSerializable30 virtual ~Serializable(){}; 31 bool Unmarshall(const std::string &content); 32 bool Marshall(std::string &content) const; UnmarshalSerializable33 virtual bool Unmarshal(cJSON *node) 34 { 35 return false; 36 } MarshalSerializable37 virtual bool Marshal(cJSON *node) const 38 { 39 return false; 40 } 41 static bool GetValue(cJSON *node, const std::string &name, std::string &value); 42 static bool GetValue(cJSON *node, const std::string &name, int32_t &value); 43 static bool GetValue(cJSON *node, const std::string &name, uint32_t &value); 44 static bool GetValue(cJSON *node, const std::string &name, bool &value); 45 static bool GetValue(cJSON *node, const std::string &name, Serializable &value); 46 static bool GetValue(cJSON *node, const std::string &name, std::vector<std::vector<std::string>> &values); 47 template<typename T> 48 static bool GetKeys(cJSON *nodes, std::vector<std::string> &keys, const std::function<bool(T)> &filter = nullptr) 49 { 50 if (nodes == nullptr) { 51 IMSA_HILOGE("nodes nullptr"); 52 return false; 53 } 54 cJSON *child = nodes->child; 55 bool result = true; 56 while (child != nullptr) { 57 std::string nodeKey = child->string; 58 T value; 59 bool ret = GetValue(child, "", value); 60 if (ret && (filter == nullptr || filter(value))) { 61 keys.push_back(nodeKey); 62 } 63 result = result && ret; 64 child = child->next; 65 } 66 return result; 67 } 68 template<typename T> 69 static bool GetValues(cJSON *nodes, std::vector<T> &values, const std::function<bool(T)> &filter = nullptr) 70 { 71 if (nodes == nullptr) { 72 IMSA_HILOGE("nodes nullptr"); 73 return false; 74 } 75 cJSON *child = nodes->child; 76 bool result = true; 77 while (child != nullptr) { 78 std::string nodeKey = child->string; 79 T value; 80 bool ret = GetValue(child, "", value); 81 if (ret && (filter == nullptr || filter(value))) { 82 values.push_back(value); 83 } 84 result = result && ret; 85 child = child->next; 86 } 87 return result; 88 } 89 template<typename T> 90 static bool GetValue(cJSON *node, const std::string &name, std::vector<T> &values, int32_t maxNum = 0) 91 { 92 auto subNode = GetSubNode(node, name); 93 if (!cJSON_IsArray(subNode)) { 94 IMSA_HILOGE("not array"); 95 return false; 96 } 97 auto size = cJSON_GetArraySize(subNode); 98 IMSA_HILOGD("size:%{public}d, maxNum:%{public}d", size, maxNum); 99 if (maxNum > 0 && size > maxNum) { 100 size = maxNum; 101 } 102 values.resize(size); 103 bool ret = true; 104 for (int32_t i = 0; i < size; i++) { 105 auto item = cJSON_GetArrayItem(subNode, i); 106 if (item == NULL) { 107 return false; 108 } 109 ret = GetValue(item, "", values[i]) && ret; 110 } 111 return ret; 112 } 113 template<typename T> 114 static bool GetValue(cJSON *node, const std::string &name, std::unordered_set<T> &values, int32_t maxNum = 0) 115 { 116 auto subNode = GetSubNode(node, name); 117 if (!cJSON_IsArray(subNode)) { 118 IMSA_HILOGE("not array"); 119 return false; 120 } 121 auto size = cJSON_GetArraySize(subNode); 122 IMSA_HILOGD("size:%{public}d, maxNum:%{public}d", size, maxNum); 123 if (maxNum > 0 && size > maxNum) { 124 size = maxNum; 125 } 126 bool result = true; 127 for (int32_t i = 0; i < size; i++) { 128 auto item = cJSON_GetArrayItem(subNode, i); 129 if (item == NULL) { 130 return false; 131 } 132 T value; 133 bool ret = GetValue(item, "", value); 134 if (ret && !values.count(value)) { 135 values.insert(value); 136 } 137 result = ret && result; 138 } 139 return result; 140 } 141 static bool SetValue(cJSON *node, const std::string &name, const std::string &value); 142 static bool SetValue(cJSON *node, const std::string &name, const int32_t &value); 143 static bool SetValue(cJSON *node, const std::string &name, const bool &value); 144 static bool SetValue(cJSON *node, const std::string &name, const Serializable &value); 145 static bool SetValue(cJSON *node, const std::string &name, const std::vector<std::vector<std::string>> &values); 146 static bool SetValue(cJSON *node, const std::string &name, const std::vector<std::string> &values); SetValueSerializable147 template<typename T> static bool SetValue(cJSON *node, const std::string &name, const std::vector<T> &values) 148 { 149 auto array = cJSON_CreateArray(); 150 for (const auto &value : values) { 151 auto *item = cJSON_CreateObject(); 152 auto ret = value.Marshal(item); 153 if (!ret || !cJSON_AddItemToArray(array, item)) { 154 cJSON_Delete(item); 155 } 156 } 157 auto ret = cJSON_AddItemToObject(node, name.c_str(), array); 158 if (!ret) { 159 cJSON_Delete(array); 160 } 161 return ret; 162 } 163 static cJSON *GetSubNode(cJSON *node, const std::string &name); 164 }; 165 } // namespace MiscServices 166 } // namespace OHOS 167 #endif // INPUT_METHOD_SERIALIZABLE_H 168