1/*
2 * Copyright (c) 2022 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 "utils_json.h"
17
18#include <stddef.h>
19
20#include "cJSON.h"
21
22#ifdef __cplusplus
23extern "C" {
24#endif
25
26DslmJsonHandle DslmCreateJson(const char *data)
27{
28    cJSON *root = NULL;
29
30    if (data != NULL) {
31        root = cJSON_Parse(data);
32    } else {
33        root = cJSON_CreateObject();
34    }
35    return (void *)root;
36}
37
38void DslmDestroyJson(DslmJsonHandle handle)
39{
40    if (handle != NULL) {
41        cJSON_Delete((cJSON *)handle);
42    }
43}
44
45int32_t DslmGetJsonFieldInt(DslmJsonHandle handle, const char *field)
46{
47    int32_t ret = -1;
48
49    if (handle == NULL) {
50        return ret;
51    }
52
53    if (field == NULL) {
54        return ((cJSON *)handle)->valueint;
55    }
56
57    cJSON *objValue = NULL;
58
59    do {
60        objValue = (cJSON *)DslmGetJsonFieldJson(handle, field);
61        if (objValue == NULL) {
62            break;
63        }
64        if (!cJSON_IsNumber(objValue)) {
65            break;
66        }
67        ret = objValue->valueint;
68    } while (0);
69
70    return ret;
71}
72
73uint32_t DslmGetJsonFieldIntArray(DslmJsonHandle handle, const char *field, int32_t *array, int32_t arrayLen)
74{
75    if (handle == NULL || field == NULL || array == NULL) {
76        return 0;
77    }
78
79    cJSON *objValue = cJSON_GetObjectItem(handle, field);
80    if (objValue == NULL) {
81        return 0;
82    }
83    if (!cJSON_IsArray(objValue)) {
84        return 0;
85    }
86
87    int size = cJSON_GetArraySize(objValue);
88    if (size > arrayLen) {
89        size = arrayLen;
90    }
91    uint32_t index = 0;
92    for (int32_t i = 0; i < size; i++) {
93        cJSON *item = cJSON_GetArrayItem(objValue, i);
94        if (!cJSON_IsNumber(item)) {
95            continue;
96        }
97        array[index++] = item->valueint;
98    }
99
100    return index;
101}
102
103void DslmAddFieldBoolToJson(DslmJsonHandle handle, const char *field, bool value)
104{
105    if (handle == NULL || field == NULL) {
106        return;
107    }
108    (void)cJSON_AddBoolToObject((cJSON *)handle, field, value);
109}
110
111const char *DslmGetJsonFieldString(DslmJsonHandle handle, const char *field)
112{
113    if (handle == NULL) {
114        return NULL;
115    }
116    if (field == NULL) {
117        return ((cJSON *)handle)->valuestring;
118    }
119    cJSON *objValue = NULL;
120    const char *payload = NULL;
121
122    do {
123        objValue = (cJSON *)DslmGetJsonFieldJson(handle, field);
124        if (objValue == NULL) {
125            break;
126        }
127        payload = cJSON_GetStringValue(objValue);
128        if (payload == NULL) {
129            break;
130        }
131    } while (0);
132    return payload;
133}
134
135DslmJsonHandle DslmGetJsonFieldJson(DslmJsonHandle handle, const char *field)
136{
137    return cJSON_GetObjectItem((cJSON *)handle, field);
138}
139
140DslmJsonHandle DslmGetJsonFieldJsonArray(DslmJsonHandle handle, uint32_t num)
141{
142    return cJSON_GetArrayItem((cJSON *)handle, num);
143}
144
145int32_t DslmGetJsonFieldJsonArraySize(DslmJsonHandle handle)
146{
147    return cJSON_GetArraySize((cJSON *)handle);
148}
149
150void DslmAddFieldIntToJson(DslmJsonHandle handle, const char *field, int32_t value)
151{
152    if (handle == NULL || field == NULL) {
153        return;
154    }
155    (void)cJSON_AddNumberToObject((cJSON *)handle, field, value);
156}
157
158void DslmAddFieldIntArrayToJson(DslmJsonHandle handle, const char *field, const int32_t *array, int32_t arrayLen)
159{
160    if (handle == NULL || field == NULL || array == NULL) {
161        return;
162    }
163    cJSON *arrayObj = cJSON_CreateIntArray(array, arrayLen);
164    if (arrayObj == NULL) {
165        return;
166    }
167    (void)cJSON_AddItemToObject((cJSON *)handle, field, arrayObj);
168}
169
170void DslmAddFieldStringToJson(DslmJsonHandle handle, const char *field, const char *value)
171{
172    if (handle == NULL || field == NULL || value == NULL) {
173        return;
174    }
175    (void)cJSON_AddStringToObject((cJSON *)handle, field, value);
176}
177
178void DslmAddFieldJsonToJson(DslmJsonHandle handle, const char *field, DslmJsonHandle json)
179{
180    if (handle == NULL || field == NULL || json == NULL) {
181        return;
182    }
183    (void)cJSON_AddItemToObject((cJSON *)handle, field, json);
184}
185
186char *DslmConvertJsonToString(DslmJsonHandle handle)
187{
188    if (handle != NULL) {
189        char *ret = cJSON_PrintUnformatted((cJSON *)handle);
190        return ret;
191    }
192    return NULL;
193}
194
195bool DslmCompareJsonData(DslmJsonHandle handleA, DslmJsonHandle handleB, bool caseSensitive)
196{
197    if (handleA == NULL || handleB == NULL) {
198        return false;
199    }
200    return cJSON_Compare(handleA, handleB, caseSensitive);
201}
202
203#ifdef __cplusplus
204}
205#endif