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 #include "serializable.h"
17 
18 namespace OHOS {
19 namespace MiscServices {
Unmarshall(const std::string & content)20 bool Serializable::Unmarshall(const std::string &content)
21 {
22     auto root = cJSON_Parse(content.c_str());
23     if (root == NULL) {
24         IMSA_HILOGE("%{public}s: parse failed!", content.c_str());
25         return false;
26     }
27     auto ret = Unmarshal(root);
28     cJSON_Delete(root);
29     return ret;
30 }
31 
Marshall(std::string & content) const32 bool Serializable::Marshall(std::string &content) const
33 {
34     cJSON *root = cJSON_CreateObject();
35     if (root == NULL) {
36         return false;
37     }
38     auto ret = Marshal(root);
39     if (!ret) {
40         cJSON_Delete(root);
41         return false;
42     }
43     auto str = cJSON_PrintUnformatted(root);
44     if (str == NULL) {
45         cJSON_Delete(root);
46         return false;
47     }
48     content = str;
49     cJSON_Delete(root);
50     cJSON_free(str);
51     return true;
52 }
53 
GetValue(cJSON * node,const std::string & name,std::string & value)54 bool Serializable::GetValue(cJSON *node, const std::string &name, std::string &value)
55 {
56     auto subNode = GetSubNode(node, name);
57     if (subNode == nullptr || !cJSON_IsString(subNode)) {
58         IMSA_HILOGD("%{public}s not string!", name.c_str());
59         return false;
60     }
61     value = subNode->valuestring;
62     return true;
63 }
64 
GetValue(cJSON * node,const std::string & name,int32_t & value)65 bool Serializable::GetValue(cJSON *node, const std::string &name, int32_t &value)
66 {
67     auto subNode = GetSubNode(node, name);
68     if (subNode == nullptr || !cJSON_IsNumber(subNode)) {
69         IMSA_HILOGD("%{public}s not number!", name.c_str());
70         return false;
71     }
72     value = subNode->valueint;
73     return true;
74 }
75 
GetValue(cJSON * node,const std::string & name,uint32_t & value)76 bool Serializable::GetValue(cJSON *node, const std::string &name, uint32_t &value)
77 {
78     auto subNode = GetSubNode(node, name);
79     if (!cJSON_IsNumber(subNode)) {
80         IMSA_HILOGD("%{public}s not number", name.c_str());
81         return false;
82     }
83     // Make sure it's not negative
84     if (subNode->valueint < 0) {
85         IMSA_HILOGD("%{public}s is negative", name.c_str());
86         return false;
87     }
88     value = static_cast<uint32_t>(subNode->valueint);
89     return true;
90 }
91 
GetValue(cJSON * node,const std::string & name,bool & value)92 bool Serializable::GetValue(cJSON *node, const std::string &name, bool &value)
93 {
94     auto subNode = GetSubNode(node, name);
95     if (subNode == nullptr || !cJSON_IsBool(subNode)) {
96         IMSA_HILOGD("%{public}s not bool", name.c_str());
97         return false;
98     }
99     value = subNode->type == cJSON_True;
100     return true;
101 }
102 
GetValue(cJSON * node,const std::string & name,Serializable & value)103 bool Serializable::GetValue(cJSON *node, const std::string &name, Serializable &value)
104 {
105     auto object = GetSubNode(node, name);
106     if (object == nullptr || !cJSON_IsObject(object)) {
107         IMSA_HILOGD("%{public}s not object", name.c_str());
108         return false;
109     }
110     return value.Unmarshal(object);
111 }
112 
SetValue(cJSON * node,const std::string & name,const std::string & value)113 bool Serializable::SetValue(cJSON *node, const std::string &name, const std::string &value)
114 {
115     auto item = cJSON_AddStringToObject(node, name.c_str(), value.c_str());
116     return item != NULL;
117 }
118 
SetValue(cJSON * node,const std::string & name,const int32_t & value)119 bool Serializable::SetValue(cJSON *node, const std::string &name, const int32_t &value)
120 {
121     auto item = cJSON_AddNumberToObject(node, name.c_str(), value);
122     return item != NULL;
123 }
124 
SetValue(cJSON * node,const std::string & name,const bool & value)125 bool Serializable::SetValue(cJSON *node, const std::string &name, const bool &value)
126 {
127     auto item = cJSON_AddBoolToObject(node, name.c_str(), value);
128     return item != NULL;
129 }
130 
GetSubNode(cJSON * node,const std::string & name)131 cJSON *Serializable::GetSubNode(cJSON *node, const std::string &name)
132 {
133     if (name.empty()) {
134         IMSA_HILOGD("end node.");
135         return node;
136     }
137     if (!cJSON_IsObject(node)) {
138         IMSA_HILOGD("not object, name:%{public}s", name.c_str());
139         return nullptr;
140     }
141     if (!cJSON_HasObjectItem(node, name.c_str())) {
142         IMSA_HILOGD("subNode: %{public}s not contain.", name.c_str());
143         return nullptr;
144     }
145     return cJSON_GetObjectItem(node, name.c_str());
146 }
147 } // namespace MiscServices
148 } // namespace OHOS
149