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#include <cJSON.h>
16
17#include "cJsonMock.h"
18
19using namespace OHOS::FileManagement::Backup;
20
21static int CaseInsensitiveStrcmp(const unsigned char *string1, const unsigned char *string2)
22{
23    if ((string1 == NULL) || (string2 == NULL)) {
24        return 1;
25    }
26
27    if (string1 == string2) {
28        return 0;
29    }
30
31    for (; tolower(*string1) == tolower(*string2); (void)string1++, string2++) {
32        if (*string1 == '\0') {
33            return 0;
34        }
35    }
36
37    return tolower(*string1) - tolower(*string2);
38}
39
40static cJSON *GetObjectItem(const cJSON * const object, const char * const name, const cJSON_bool caseSensitive)
41{
42    cJSON *current_element = NULL;
43
44    if ((object == NULL) || (name == NULL)) {
45        return NULL;
46    }
47
48    current_element = object->child;
49    if (caseSensitive) {
50        while ((current_element != NULL) && (current_element->string != NULL) &&
51            (strcmp(name, current_element->string) != 0)) {
52            current_element = current_element->next;
53        }
54    } else {
55        while ((current_element != NULL) &&
56            (CaseInsensitiveStrcmp((const unsigned char*)name, (const unsigned char*)(current_element->string)) != 0)) {
57            current_element = current_element->next;
58        }
59    }
60
61    if ((current_element == NULL) || (current_element->string == NULL)) {
62        return NULL;
63    }
64
65    return current_element;
66}
67
68CJSON_PUBLIC(void) CJSONDelete(cJSON *item)
69{
70    cJSON *next = NULL;
71    while (item != NULL)
72    {
73        next = item->next;
74        if (!(item->type & cJSON_IsReference) && (item->child != NULL))
75        {
76            CJSONDelete(item->child);
77        }
78        if (!(item->type & cJSON_IsReference) && (item->valuestring != NULL))
79        {
80            free(item->valuestring);
81            item->valuestring = NULL;
82        }
83        if (!(item->type & cJSON_StringIsConst) && (item->string != NULL))
84        {
85            free(item->string);
86            item->string = NULL;
87        }
88        if (next == item)
89        {
90            break;
91        }
92        free(item);
93        item = next;
94    }
95}
96
97CJSON_PUBLIC(cJSON *) cJSON_CreateArray(void)
98{
99    return CJson::cJsonPtr->cJSON_CreateArray();
100}
101
102CJSON_PUBLIC(cJSON *) cJSON_CreateObject(void)
103{
104    return CJson::cJsonPtr->cJSON_CreateObject();
105}
106
107CJSON_PUBLIC(char *) cJSON_Print(const cJSON *item)
108{
109    return CJson::cJsonPtr->cJSON_Print(item);
110}
111
112CJSON_PUBLIC(cJSON *) cJSON_Parse(const char *value)
113{
114    return (CJson::cJsonPtr == nullptr) ? cJSON_ParseWithOpts(value, 0, 0) : CJson::cJsonPtr->cJSON_Parse(value);
115}
116
117CJSON_PUBLIC(cJSON *) cJSON_GetObjectItem(const cJSON *const object, const char *const string)
118{
119    return (CJson::cJsonPtr == nullptr) ? GetObjectItem(object, string, false) :
120        CJson::cJsonPtr->cJSON_GetObjectItem(object, string);
121}
122
123CJSON_PUBLIC(void) cJSON_Delete(cJSON *item)
124{
125    return (CJson::cJsonPtr == nullptr) ? CJSONDelete(item) : CJson::cJsonPtr->cJSON_Delete(item);
126}
127
128CJSON_PUBLIC(cJSON_bool) cJSON_AddItemToObject(cJSON *object, const char *string, cJSON *item)
129{
130    return CJson::cJsonPtr->cJSON_AddItemToObject(object, string, item);
131}
132
133CJSON_PUBLIC(int) cJSON_GetArraySize(const cJSON *array)
134{
135    return CJson::cJsonPtr->cJSON_GetArraySize(array);
136}
137
138CJSON_PUBLIC(cJSON_bool) cJSON_AddItemToArray(cJSON *array, cJSON *item)
139{
140    return CJson::cJsonPtr->cJSON_AddItemToArray(array, item);
141}
142
143CJSON_PUBLIC(cJSON*) cJSON_AddStringToObject(cJSON * const object, const char * const name, const char * const string)
144{
145    return CJson::cJsonPtr->cJSON_AddStringToObject(object, name, string);
146}
147
148static CJSON_PUBLIC(cJSON_bool) IsArray(const cJSON * const item)
149{
150    if (item == NULL) {
151        return false;
152    }
153
154    return (item->type & 0xFF) == cJSON_Array;
155}
156
157CJSON_PUBLIC(cJSON_bool) cJSON_IsArray(const cJSON * const item)
158{
159    return (CJson::cJsonPtr == nullptr) ? IsArray(item) : CJson::cJsonPtr->cJSON_IsArray(item);
160}
161
162CJSON_PUBLIC(void) cJSON_free(void *object)
163{
164    return (CJson::cJsonPtr == nullptr) ? free(object) : CJson::cJsonPtr->cJSON_free(object);
165}