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 <vector>
20
21#include "cJSON.h"
22#include "global.h"
23namespace OHOS {
24namespace MiscServices {
25#ifndef GET_NAME
26#define GET_NAME(value) #value
27#endif
28struct Serializable {
29public:
30    virtual ~Serializable(){};
31    bool Unmarshall(const std::string &content);
32    bool Marshall(std::string &content) const;
33    virtual bool Unmarshal(cJSON *node) = 0;
34    virtual bool Marshal(cJSON *node) const
35    {
36        return false;
37    }
38    static bool GetValue(cJSON *node, const std::string &name, std::string &value);
39    static bool GetValue(cJSON *node, const std::string &name, int32_t &value);
40    static bool GetValue(cJSON *node, const std::string &name, uint32_t &value);
41    static bool GetValue(cJSON *node, const std::string &name, bool &value);
42    static bool GetValue(cJSON *node, const std::string &name, Serializable &value);
43    template<typename T>
44    static bool GetValue(cJSON *node, const std::string &name, std::vector<T> &values, int32_t maxNum = 0)
45    {
46        auto subNode = GetSubNode(node, name);
47        if (!cJSON_IsArray(subNode)) {
48            IMSA_HILOGE("not array");
49            return false;
50        }
51        auto size = cJSON_GetArraySize(subNode);
52        IMSA_HILOGD("size:%{public}d, maxNum:%{public}d", size, maxNum);
53        if (maxNum > 0 && size > maxNum) {
54            size = maxNum;
55        }
56        values.resize(size);
57        bool ret = true;
58        for (int32_t i = 0; i < size; i++) {
59            auto item = cJSON_GetArrayItem(subNode, i);
60            if (item == NULL) {
61                return false;
62            }
63            ret = GetValue(item, "", values[i]) && ret;
64        }
65        return ret;
66    }
67    static bool SetValue(cJSON *node, const std::string &name, const std::string &value);
68    static bool SetValue(cJSON *node, const std::string &name, const int32_t &value);
69    template<typename T> static bool SetValue(cJSON *node, const std::string &name, const std::vector<T> &values)
70    {
71        auto array = cJSON_CreateArray();
72        for (const auto &value : values) {
73            auto *item = cJSON_CreateObject();
74            auto ret = value.Marshal(item);
75            if (!ret || !cJSON_AddItemToArray(array, item)) {
76                cJSON_Delete(item);
77            }
78        }
79        auto ret = cJSON_AddItemToObject(node, name.c_str(), array);
80        if (!ret) {
81            cJSON_Delete(array);
82        }
83        return ret;
84    }
85
86private:
87    static cJSON *GetSubNode(cJSON *node, const std::string &name);
88};
89} // namespace MiscServices
90} // namespace OHOS
91#endif // INPUT_METHOD_SERIALIZABLE_H
92