• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 // LCOV_EXCL_START
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 // LCOV_EXCL_STOP
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 // LCOV_EXCL_START
GetValue(cJSON * node,const std::string & name,std::vector<std::vector<std::string>> & values)113 bool Serializable::GetValue(cJSON *node, const std::string &name, std::vector<std::vector<std::string>> &values)
114 {
115     auto arrNode = GetSubNode(node, name);
116     if (arrNode == nullptr || !cJSON_IsArray(arrNode)) {
117         IMSA_HILOGD("%{public}s not array", name.c_str());
118         return false;
119     }
120     auto arrLen = cJSON_GetArraySize(arrNode);
121     for (auto i = 0; i < arrLen; i++) {
122         auto subArrNode = cJSON_GetArrayItem(arrNode, i);
123         if (subArrNode == nullptr || !cJSON_IsArray(subArrNode)) {
124             continue;
125         }
126         std::vector<std::string> subStringArr;
127         auto subArrLen = cJSON_GetArraySize(subArrNode);
128         for (auto j = 0; j < subArrLen; j++) {
129             auto strNode = cJSON_GetArrayItem(subArrNode, j);
130             if (strNode == nullptr || !cJSON_IsString(strNode)) {
131                 continue;
132             }
133             subStringArr.push_back(strNode->valuestring);
134         }
135         values.push_back(subStringArr);
136     }
137     return true;
138 }
139 // LCOV_EXCL_STOP
SetValue(cJSON * node,const std::string & name,const std::string & value)140 bool Serializable::SetValue(cJSON *node, const std::string &name, const std::string &value)
141 {
142     auto item = cJSON_AddStringToObject(node, name.c_str(), value.c_str());
143     return item != NULL;
144 }
145 
SetValue(cJSON * node,const std::string & name,const int32_t & value)146 bool Serializable::SetValue(cJSON *node, const std::string &name, const int32_t &value)
147 {
148     auto item = cJSON_AddNumberToObject(node, name.c_str(), value);
149     return item != NULL;
150 }
151 
SetValue(cJSON * node,const std::string & name,const bool & value)152 bool Serializable::SetValue(cJSON *node, const std::string &name, const bool &value)
153 {
154     auto item = cJSON_AddBoolToObject(node, name.c_str(), value);
155     return item != NULL;
156 }
157 
SetValue(cJSON * node,const std::string & name,const Serializable & value)158 bool Serializable::SetValue(cJSON *node, const std::string &name, const Serializable &value)
159 {
160     cJSON *item = cJSON_CreateObject();
161     if (item == NULL) {
162         return false;
163     }
164     if (!value.Marshal(item)) {
165         cJSON_Delete(item);
166         return false;
167     }
168     auto ret = cJSON_AddItemToObject(node, name.c_str(), item);
169     if (!ret) {
170         cJSON_Delete(item);
171     }
172     return ret;
173 }
174 
SetValue(cJSON * node,const std::string & name,const std::vector<std::string> & values)175 bool Serializable::SetValue(cJSON *node, const std::string &name, const std::vector<std::string> &values)
176 {
177     const char **strArr = new (std::nothrow) const char *[values.size()];
178     if (strArr == nullptr) {
179         return false;
180     }
181     for (size_t i = 0; i < values.size(); i++) {
182         strArr[i] = values[i].c_str();
183     }
184     cJSON *stringArray = cJSON_CreateStringArray(strArr, values.size());
185     if (stringArray == NULL) {
186         delete[] strArr;
187         return false;
188     }
189 
190     auto ret = cJSON_AddItemToObject(node, name.c_str(), stringArray);
191     if (!ret) {
192         cJSON_Delete(stringArray);
193     }
194     delete[] strArr;
195     return ret;
196 }
197 
SetValue(cJSON * node,const std::string & name,const std::vector<std::vector<std::string>> & values)198 bool Serializable::SetValue(cJSON *node, const std::string &name, const std::vector<std::vector<std::string>> &values)
199 {
200     cJSON *array = cJSON_CreateArray();
201     if (array == NULL) {
202         return false;
203     }
204     for (const auto &value : values) {
205         const char **strArr = new (std::nothrow) const char *[value.size()];
206         if (strArr == nullptr) {
207             continue;
208         }
209         for (size_t i = 0; i < value.size(); i++) {
210             strArr[i] = value[i].c_str();
211         }
212         cJSON *stringArray = cJSON_CreateStringArray(strArr, value.size());
213         if (stringArray == NULL) {
214             delete[] strArr;
215             continue;
216         }
217         auto ret = cJSON_AddItemToArray(array, stringArray);
218         if (!ret) {
219             cJSON_Delete(stringArray);
220         }
221         delete[] strArr;
222     }
223     auto ret = cJSON_AddItemToObject(node, name.c_str(), array);
224     if (!ret) {
225         cJSON_Delete(array);
226     }
227     return ret;
228 }
229 
GetSubNode(cJSON * node,const std::string & name)230 cJSON *Serializable::GetSubNode(cJSON *node, const std::string &name)
231 {
232     if (name.empty()) {
233         IMSA_HILOGD("end node.");
234         return node;
235     }
236     if (!cJSON_IsObject(node)) {
237         IMSA_HILOGD("not object, name:%{public}s", name.c_str());
238         return nullptr;
239     }
240     if (!cJSON_HasObjectItem(node, name.c_str())) {
241         IMSA_HILOGD("subNode: %{public}s not contain.", name.c_str());
242         return nullptr;
243     }
244     return cJSON_GetObjectItem(node, name.c_str());
245 }
246 } // namespace MiscServices
247 } // namespace OHOS