21 #if !defined(_CRT_SECURE_NO_DEPRECATE) && defined(_MSC_VER) 22 #define _CRT_SECURE_NO_DEPRECATE 26 #pragma GCC visibility push(default) 29 #pragma warning (push) 31 #pragma warning (disable : 4001) 44 #pragma GCC visibility pop 53 #define true ((cJSON_bool)1) 58 #define false ((cJSON_bool)0) 63 unsigned char *copy = NULL;
65 length = strlen((
const char*)
string) +
sizeof(
"");
66 copy = (
unsigned char*) cJSON_malloc(length);
71 memcpy(copy,
string, length);
79 if ((string1 == NULL) || (string2 == NULL))
84 if (string1 == string2)
91 return strcmp((
const char*)string1, (
const char*)string2);
94 for(; tolower(*string1) == tolower(*string2); (void)string1++, string2++)
102 return tolower(*string1) - tolower(*string2);
108 if ((name == NULL) || (pointer == NULL))
113 for (; (*name !=
'\0') && (*pointer !=
'\0') && (*pointer !=
'/'); (void)name++, pointer++)
118 if (((pointer[1] !=
'0') || (*name !=
'~')) && ((pointer[1] !=
'1') || (*name !=
'/')))
128 else if ((!case_sensitive && (tolower(*name) != tolower(*pointer))) || (case_sensitive && (*name != *
pointer)))
133 if (((*pointer != 0) && (*pointer !=
'/')) != (*name != 0))
146 for (length = 0; *
string !=
'\0'; (void)
string++, length++)
149 if ((*
string ==
'~') || (*
string ==
'/'))
161 for (; source[0] !=
'\0'; (void)source++, destination++)
163 if (source[0] ==
'/')
165 destination[1] =
'1';
168 else if (source[0] ==
'~')
170 destination[0] =
'~';
171 destination[1] =
'1';
176 destination[0] = source[0];
180 destination[0] =
'\0';
185 size_t child_index = 0;
186 cJSON *current_child = 0;
188 if ((
object == NULL) || (target == NULL))
193 if (
object == target)
200 for (current_child = object->
child; current_child != NULL; (
void)(current_child = current_child->
next), child_index++)
202 unsigned char *target_pointer = (
unsigned char*)cJSONUtils_FindPointerFromObjectTo(current_child, target);
204 if (target_pointer != NULL)
206 if (cJSON_IsArray(
object))
209 unsigned char *full_pointer = (
unsigned char*)cJSON_malloc(strlen((
char*)target_pointer) + 20 +
sizeof(
"/"));
213 if (child_index > ULONG_MAX)
215 cJSON_free(target_pointer);
218 sprintf((
char*)full_pointer,
"/%lu%s", (
unsigned long)child_index, target_pointer);
219 cJSON_free(target_pointer);
221 return (
char*)full_pointer;
224 if (cJSON_IsObject(
object))
226 unsigned char *full_pointer = (
unsigned char*)cJSON_malloc(strlen((
char*)target_pointer) +
pointer_encoded_length((
unsigned char*)current_child->
string) + 2);
227 full_pointer[0] =
'/';
229 strcat((
char*)full_pointer, (
char*)target_pointer);
230 cJSON_free(target_pointer);
232 return (
char*)full_pointer;
236 cJSON_free(target_pointer);
249 while ((child != NULL) && (item > 0))
260 size_t parsed_index = 0;
263 if ((pointer[0] ==
'0') && ((pointer[1] !=
'\0') && (pointer[1] !=
'/')))
269 for (position = 0; (pointer[position] >=
'0') && (pointer[0] <=
'9'); position++)
271 parsed_index = (10 * parsed_index) + (
size_t)(pointer[position] -
'0');
275 if ((pointer[position] !=
'\0') && (pointer[position] !=
'/'))
280 *index = parsed_index;
287 cJSON *current_element = object;
295 while ((pointer[0] ==
'/') && (current_element != NULL))
298 if (cJSON_IsArray(current_element))
308 else if (cJSON_IsObject(current_element))
310 current_element = current_element->
child;
312 while ((current_element != NULL) && !
compare_pointers((
unsigned char*)current_element->
string, (
const unsigned char*)pointer, case_sensitive))
314 current_element = current_element->
next;
323 while ((pointer[0] !=
'\0') && (pointer[0] !=
'/'))
329 return current_element;
345 unsigned char *decoded_string =
string;
347 if (
string == NULL) {
351 for (; *
string; (void)decoded_string++,
string++)
353 if (
string[0] ==
'~')
355 if (
string[1] ==
'0')
357 decoded_string[0] =
'~';
359 else if (
string[1] ==
'1')
361 decoded_string[1] =
'/';
373 decoded_string[0] =
'\0';
380 while (c && (which > 0))
412 unsigned char *parent_pointer = NULL;
413 unsigned char *child_pointer = NULL;
414 cJSON *parent = NULL;
415 cJSON *detached_item = NULL;
419 if (parent_pointer == NULL) {
423 child_pointer = (
unsigned char*)strrchr((
char*)parent_pointer,
'/');
424 if (child_pointer == NULL)
429 child_pointer[0] =
'\0';
435 if (cJSON_IsArray(parent))
444 else if (cJSON_IsObject(parent))
446 detached_item = cJSON_DetachItemFromObject(parent, (
char*)child_pointer);
455 if (parent_pointer != NULL)
457 cJSON_free(parent_pointer);
460 return detached_item;
467 cJSON *second = list;
468 cJSON *current_item = list;
469 cJSON *result = list;
470 cJSON *result_tail = NULL;
472 if ((list == NULL) || (list->
next == NULL))
478 while ((current_item != NULL) && (current_item->
next != NULL) && (
compare_strings((
unsigned char*)current_item->
string, (
unsigned char*)current_item->
next->
string, case_sensitive) < 0))
481 current_item = current_item->
next;
483 if ((current_item == NULL) || (current_item->
next == NULL))
491 while (current_item != NULL)
494 second = second->
next;
495 current_item = current_item->
next;
497 if (current_item != NULL)
499 current_item = current_item->
next;
502 if ((second != NULL) && (second->
prev != NULL))
510 first =
sort_list(first, case_sensitive);
511 second =
sort_list(second, case_sensitive);
515 while ((first != NULL) && (second != NULL))
517 cJSON *smaller = NULL;
530 result_tail = smaller;
536 result_tail->
next = smaller;
537 smaller->
prev = result_tail;
538 result_tail = smaller;
541 if (first == smaller)
547 second = second->
next;
558 result_tail->
next = first;
559 first->
prev = result_tail;
568 result_tail->
next = second;
569 second->
prev = result_tail;
586 if ((a == NULL) || (b == NULL) || ((a->
type & 0xFF) != (b->
type & 0xFF)))
591 switch (a->
type & 0xFF)
616 for ((
void)(a = a->
child), b = b->
child; (a != NULL) && (b != NULL); (
void)(a = a->
next), b = b->
next)
626 if ((a != NULL) || (b != NULL))
638 for ((
void)(a = a->
child), b = b->
child; (a != NULL) && (b != NULL); (
void)(a = a->
next), b = b->
next)
655 if ((a != NULL) || (b != NULL))
676 while (child && (which > 0))
688 cJSON_AddItemToArray(array, newitem);
693 newitem->
next = child;
698 if (child == array->
child)
714 return cJSON_GetObjectItemCaseSensitive(
object, name);
717 return cJSON_GetObjectItem(
object, name);
725 if (!cJSON_IsString(operation))
740 if (strcmp(operation->
valuestring,
"replace") == 0)
779 if (root->
child != NULL)
781 cJSON_Delete(root->
child);
784 memcpy(root, &replacement,
sizeof(
cJSON));
791 cJSON *parent = NULL;
793 unsigned char *parent_pointer = NULL;
794 unsigned char *child_pointer = NULL;
798 if (!cJSON_IsString(path))
811 else if (opcode ==
TEST)
841 value = cJSON_Duplicate(value, 1);
856 if (object->
string != NULL)
858 cJSON_free(object->
string);
859 object->string = NULL;
871 if (old_item == NULL)
876 cJSON_Delete(old_item);
886 if ((opcode ==
MOVE) || (opcode ==
COPY))
912 value = cJSON_Duplicate(value, 1);
930 value = cJSON_Duplicate(value, 1);
943 child_pointer = (
unsigned char*)strrchr((
char*)parent_pointer,
'/');
944 if (child_pointer != NULL)
946 child_pointer[0] =
'\0';
953 if ((parent == NULL) || (child_pointer == NULL))
959 else if (cJSON_IsArray(parent))
961 if (strcmp((
char*)child_pointer,
"-") == 0)
963 cJSON_AddItemToArray(parent, value);
983 else if (cJSON_IsObject(parent))
987 cJSON_DeleteItemFromObjectCaseSensitive(parent, (
char*)child_pointer);
991 cJSON_DeleteItemFromObject(parent, (
char*)child_pointer);
993 cJSON_AddItemToObject(parent, (
char*)child_pointer, value);
1006 cJSON_Delete(value);
1008 if (parent_pointer != NULL)
1010 cJSON_free(parent_pointer);
1018 const cJSON *current_patch = NULL;
1021 if (!cJSON_IsArray(patches))
1027 if (patches != NULL)
1029 current_patch = patches->
child;
1032 while (current_patch != NULL)
1034 status =
apply_patch(
object, current_patch,
false);
1039 current_patch = current_patch->
next;
1047 const cJSON *current_patch = NULL;
1050 if (!cJSON_IsArray(patches))
1056 if (patches != NULL)
1058 current_patch = patches->
child;
1061 while (current_patch != NULL)
1063 status =
apply_patch(
object, current_patch,
true);
1068 current_patch = current_patch->
next;
1078 if ((patches == NULL) || (operation == NULL) || (path == NULL))
1083 patch = cJSON_CreateObject();
1088 cJSON_AddItemToObject(patch,
"op", cJSON_CreateString((
const char*)operation));
1092 cJSON_AddItemToObject(patch,
"path", cJSON_CreateString((
const char*)path));
1097 size_t path_length = strlen((
const char*)path);
1098 unsigned char *full_path = (
unsigned char*)cJSON_malloc(path_length + suffix_length +
sizeof(
"/"));
1100 sprintf((
char*)full_path,
"%s/", (
const char*)path);
1103 cJSON_AddItemToObject(patch,
"path", cJSON_CreateString((
const char*)full_path));
1104 cJSON_free(full_path);
1109 cJSON_AddItemToObject(patch,
"value", cJSON_Duplicate(value, 1));
1111 cJSON_AddItemToArray(patches, patch);
1116 compose_patch(array, (
const unsigned char*)operation, (
const unsigned char*)path, NULL, value);
1121 if ((from == NULL) || (to == NULL))
1126 if ((from->
type & 0xFF) != (to->
type & 0xFF))
1128 compose_patch(patches, (
const unsigned char*)
"replace", path, 0, to);
1132 switch (from->
type & 0xFF)
1137 compose_patch(patches, (
const unsigned char*)
"replace", path, NULL, to);
1144 compose_patch(patches, (
const unsigned char*)
"replace", path, NULL, to);
1153 unsigned char *new_path = (
unsigned char*)cJSON_malloc(strlen((
const char*)path) + 20 +
sizeof(
"/"));
1156 for (index = 0; (from_child != NULL) && (to_child != NULL); (void)(from_child = from_child->
next), (void)(to_child = to_child->
next), index++)
1161 if (index > ULONG_MAX)
1163 cJSON_free(new_path);
1166 sprintf((
char*)new_path,
"%s/%lu", path, (
unsigned long)index);
1167 create_patches(patches, new_path, from_child, to_child, case_sensitive);
1171 for (; (from_child != NULL); (void)(from_child = from_child->
next))
1176 if (index > ULONG_MAX)
1178 cJSON_free(new_path);
1181 sprintf((
char*)new_path,
"%lu", (
unsigned long)index);
1182 compose_patch(patches, (
const unsigned char*)
"remove", path, new_path, NULL);
1185 for (; (to_child != NULL); (void)(to_child = to_child->
next), index++)
1187 compose_patch(patches, (
const unsigned char*)
"add", path, (
const unsigned char*)
"-", to_child);
1189 cJSON_free(new_path);
1195 cJSON *from_child = NULL;
1196 cJSON *to_child = NULL;
1200 from_child = from->
child;
1201 to_child = to->
child;
1203 while ((from_child != NULL) || (to_child != NULL))
1206 if (from_child == NULL)
1210 else if (to_child == NULL)
1222 size_t path_length = strlen((
const char*)path);
1224 unsigned char *new_path = (
unsigned char*)cJSON_malloc(path_length + from_child_name_length +
sizeof(
"/"));
1226 sprintf((
char*)new_path,
"%s/", path);
1230 create_patches(patches, new_path, from_child, to_child, case_sensitive);
1231 cJSON_free(new_path);
1233 from_child = from_child->
next;
1234 to_child = to_child->
next;
1239 compose_patch(patches, (
const unsigned char*)
"remove", path, (
unsigned char*)from_child->
string, NULL);
1241 from_child = from_child->
next;
1246 compose_patch(patches, (
const unsigned char*)
"add", path, (
unsigned char*)to_child->
string, to_child);
1248 to_child = to_child->
next;
1261 cJSON *patches = NULL;
1263 if ((from == NULL) || (to == NULL))
1268 patches = cJSON_CreateArray();
1269 create_patches(patches, (
const unsigned char*)
"", from, to,
false);
1276 cJSON *patches = NULL;
1278 if ((from == NULL) || (to == NULL))
1283 patches = cJSON_CreateArray();
1284 create_patches(patches, (
const unsigned char*)
"", from, to,
true);
1301 cJSON *patch_child = NULL;
1303 if (!cJSON_IsObject(patch))
1306 cJSON_Delete(target);
1307 return cJSON_Duplicate(patch, 1);
1310 if (!cJSON_IsObject(target))
1312 cJSON_Delete(target);
1313 target = cJSON_CreateObject();
1316 patch_child = patch->
child;
1317 while (patch_child != NULL)
1319 if (cJSON_IsNull(patch_child))
1324 cJSON_DeleteItemFromObjectCaseSensitive(target, patch_child->
string);
1328 cJSON_DeleteItemFromObject(target, patch_child->
string);
1333 cJSON *replace_me = NULL;
1338 replace_me = cJSON_DetachItemFromObjectCaseSensitive(target, patch_child->
string);
1342 replace_me = cJSON_DetachItemFromObject(target, patch_child->
string);
1345 replacement =
merge_patch(replace_me, patch_child, case_sensitive);
1346 if (replacement == NULL)
1351 cJSON_AddItemToObject(target, patch_child->
string, replacement);
1353 patch_child = patch_child->
next;
1370 cJSON *from_child = NULL;
1371 cJSON *to_child = NULL;
1372 cJSON *patch = NULL;
1376 return cJSON_CreateNull();
1378 if (!cJSON_IsObject(to) || !cJSON_IsObject(from))
1380 return cJSON_Duplicate(to, 1);
1386 from_child = from->
child;
1387 to_child = to->
child;
1388 patch = cJSON_CreateObject();
1389 while (from_child || to_child)
1392 if (from_child != NULL)
1394 if (to_child != NULL)
1411 cJSON_AddItemToObject(patch, from_child->
string, cJSON_CreateNull());
1413 from_child = from_child->
next;
1418 cJSON_AddItemToObject(patch, to_child->
string, cJSON_Duplicate(to_child, 1));
1420 to_child = to_child->
next;
1425 if (!
compare_json(from_child, to_child, case_sensitive))
1428 cJSON_AddItemToObject(patch, to_child->
string, cJSONUtils_GenerateMergePatch(from_child, to_child));
1432 from_child = from_child->
next;
1433 to_child = to_child->
next;
1436 if (patch->
child == NULL)
1439 cJSON_Delete(patch);
static void compose_patch(cJSON *const patches, const unsigned char *const operation, const unsigned char *const path, const unsigned char *suffix, const cJSON *const value)
const char *const const char *const const cJSON *const value
static cJSON_bool insert_item_in_array(cJSON *array, size_t which, cJSON *newitem)
static cJSON * merge_patch(cJSON *target, const cJSON *const patch, const cJSON_bool case_sensitive)
static void sort_object(cJSON *const object, const cJSON_bool case_sensitive)
static void decode_pointer_inplace(unsigned char *string)
static cJSON_bool compare_json(cJSON *a, cJSON *b, const cJSON_bool case_sensitive)
static cJSON * detach_item_from_array(cJSON *array, size_t which)
static cJSON * get_item_from_pointer(cJSON *const object, const char *pointer, const cJSON_bool case_sensitive)
static void create_patches(cJSON *const patches, const unsigned char *const path, cJSON *const from, cJSON *const to, const cJSON_bool case_sensitive)
static cJSON * sort_list(cJSON *list, const cJSON_bool case_sensitive)
static cJSON * get_object_item(const cJSON *const object, const char *name, const cJSON_bool case_sensitive)
const cJSON *const const cJSON_bool case_sensitive
const cJSON *const patches
static void encode_string_as_pointer(unsigned char *destination, const unsigned char *source)
static cJSON_bool compare_pointers(const unsigned char *name, const unsigned char *pointer, const cJSON_bool case_sensitive)
const char *const operation
cJSON *const cJSON * replacement
static unsigned char * cJSONUtils_strdup(const unsigned char *const string)
static cJSON * generate_merge_patch(cJSON *const from, cJSON *const to, const cJSON_bool case_sensitive)
const char *const const char *const path
const cJSON *const target
static enum patch_operation decode_patch_operation(const cJSON *const patch, const cJSON_bool case_sensitive)
static int compare_strings(const unsigned char *string1, const unsigned char *string2, const cJSON_bool case_sensitive)
static cJSON * detach_path(cJSON *object, const unsigned char *path, const cJSON_bool case_sensitive)
static int apply_patch(cJSON *object, const cJSON *patch, const cJSON_bool case_sensitive)
static size_t pointer_encoded_length(const unsigned char *string)
static cJSON_bool decode_array_index_from_pointer(const unsigned char *const pointer, size_t *const index)
static cJSON * get_array_item(const cJSON *array, size_t item)
static void overwrite_item(cJSON *const root, const cJSON replacement)