@@ -425,6 +425,122 @@ static cJSON *detach_path(cJSON *object, const unsigned char *path, const cJSON_
425425 return detached_item ;
426426}
427427
428+ /* sort lists using mergesort */
429+ static cJSON * sort_list (cJSON * list , const cJSON_bool case_sensitive )
430+ {
431+ cJSON * first = list ;
432+ cJSON * second = list ;
433+ cJSON * current_item = list ;
434+ cJSON * result = list ;
435+ cJSON * result_tail = NULL ;
436+
437+ if ((list == NULL ) || (list -> next == NULL ))
438+ {
439+ /* One entry is sorted already. */
440+ return result ;
441+ }
442+
443+ while ((current_item != NULL ) && (current_item -> next != NULL ) && (compare_strings ((unsigned char * )current_item -> string , (unsigned char * )current_item -> next -> string , case_sensitive ) < 0 ))
444+ {
445+ /* Test for list sorted. */
446+ current_item = current_item -> next ;
447+ }
448+ if ((current_item == NULL ) || (current_item -> next == NULL ))
449+ {
450+ /* Leave sorted lists unmodified. */
451+ return result ;
452+ }
453+
454+ /* reset pointer to the beginning */
455+ current_item = list ;
456+ while (current_item != NULL )
457+ {
458+ /* Walk two pointers to find the middle. */
459+ second = second -> next ;
460+ current_item = current_item -> next ;
461+ /* advances current_item two steps at a time */
462+ if (current_item != NULL )
463+ {
464+ current_item = current_item -> next ;
465+ }
466+ }
467+ if ((second != NULL ) && (second -> prev != NULL ))
468+ {
469+ /* Split the lists */
470+ second -> prev -> next = NULL ;
471+ }
472+
473+ /* Recursively sort the sub-lists. */
474+ first = sort_list (first , case_sensitive );
475+ second = sort_list (second , case_sensitive );
476+ result = NULL ;
477+
478+ /* Merge the sub-lists */
479+ while ((first != NULL ) && (second != NULL ))
480+ {
481+ cJSON * smaller = NULL ;
482+ if (compare_strings ((unsigned char * )first -> string , (unsigned char * )second -> string , false) < 0 )
483+ {
484+ smaller = first ;
485+ }
486+ else
487+ {
488+ smaller = second ;
489+ }
490+
491+ if (result == NULL )
492+ {
493+ /* start merged list with the smaller element */
494+ result_tail = smaller ;
495+ result = smaller ;
496+ }
497+ else
498+ {
499+ /* add smaller element to the list */
500+ result_tail -> next = smaller ;
501+ smaller -> prev = result_tail ;
502+ result_tail = smaller ;
503+ }
504+
505+ if (first == smaller )
506+ {
507+ first = first -> next ;
508+ }
509+ else
510+ {
511+ second = second -> next ;
512+ }
513+ }
514+
515+ if (first != NULL )
516+ {
517+ /* Append rest of first list. */
518+ if (result == NULL )
519+ {
520+ return first ;
521+ }
522+ result_tail -> next = first ;
523+ first -> prev = result_tail ;
524+ }
525+ if (second != NULL )
526+ {
527+ /* Append rest of second list */
528+ if (result == NULL )
529+ {
530+ return second ;
531+ }
532+ result_tail -> next = second ;
533+ second -> prev = result_tail ;
534+ }
535+
536+ return result ;
537+ }
538+
539+ static void sort_object (cJSON * const object , const cJSON_bool case_sensitive )
540+ {
541+ object -> child = sort_list (object -> child , case_sensitive );
542+ }
543+
428544static cJSON_bool compare_json (cJSON * a , cJSON * b , const cJSON_bool case_sensitive )
429545{
430546 if ((a == NULL ) || (b == NULL ) || ((a -> type & 0xFF ) != (b -> type & 0xFF )))
@@ -477,8 +593,8 @@ static cJSON_bool compare_json(cJSON *a, cJSON *b, const cJSON_bool case_sensiti
477593 }
478594
479595 case cJSON_Object :
480- cJSONUtils_SortObject ( a );
481- cJSONUtils_SortObject ( b );
596+ sort_object ( a , case_sensitive );
597+ sort_object ( b , case_sensitive );
482598 for ((void )(a = a -> child ), b = b -> child ; (a != NULL ) && (b != NULL ); (void )(a = a -> next ), b = b -> next )
483599 {
484600 cJSON_bool identical = false;
@@ -1018,8 +1134,8 @@ static void create_patches(cJSON * const patches, const unsigned char * const pa
10181134 {
10191135 cJSON * from_child = NULL ;
10201136 cJSON * to_child = NULL ;
1021- cJSONUtils_SortObject (from );
1022- cJSONUtils_SortObject (to );
1137+ sort_object (from , case_sensitive );
1138+ sort_object (to , case_sensitive );
10231139
10241140 from_child = from -> child ;
10251141 to_child = to -> child ;
@@ -1096,120 +1212,14 @@ CJSON_PUBLIC(cJSON *) cJSONUtils_GeneratePatchesCaseSensitive(cJSON * const from
10961212 return patches ;
10971213}
10981214
1099- /* sort lists using mergesort */
1100- static cJSON * sort_list (cJSON * list , const cJSON_bool case_sensitive )
1215+ CJSON_PUBLIC (void ) cJSONUtils_SortObject (cJSON * const object )
11011216{
1102- cJSON * first = list ;
1103- cJSON * second = list ;
1104- cJSON * current_item = list ;
1105- cJSON * result = list ;
1106- cJSON * result_tail = NULL ;
1107-
1108- if ((list == NULL ) || (list -> next == NULL ))
1109- {
1110- /* One entry is sorted already. */
1111- return result ;
1112- }
1113-
1114- while ((current_item != NULL ) && (current_item -> next != NULL ) && (compare_strings ((unsigned char * )current_item -> string , (unsigned char * )current_item -> next -> string , case_sensitive ) < 0 ))
1115- {
1116- /* Test for list sorted. */
1117- current_item = current_item -> next ;
1118- }
1119- if ((current_item == NULL ) || (current_item -> next == NULL ))
1120- {
1121- /* Leave sorted lists unmodified. */
1122- return result ;
1123- }
1124-
1125- /* reset pointer to the beginning */
1126- current_item = list ;
1127- while (current_item != NULL )
1128- {
1129- /* Walk two pointers to find the middle. */
1130- second = second -> next ;
1131- current_item = current_item -> next ;
1132- /* advances current_item two steps at a time */
1133- if (current_item != NULL )
1134- {
1135- current_item = current_item -> next ;
1136- }
1137- }
1138- if ((second != NULL ) && (second -> prev != NULL ))
1139- {
1140- /* Split the lists */
1141- second -> prev -> next = NULL ;
1142- }
1143-
1144- /* Recursively sort the sub-lists. */
1145- first = sort_list (first , case_sensitive );
1146- second = sort_list (second , case_sensitive );
1147- result = NULL ;
1148-
1149- /* Merge the sub-lists */
1150- while ((first != NULL ) && (second != NULL ))
1151- {
1152- cJSON * smaller = NULL ;
1153- if (compare_strings ((unsigned char * )first -> string , (unsigned char * )second -> string , false) < 0 )
1154- {
1155- smaller = first ;
1156- }
1157- else
1158- {
1159- smaller = second ;
1160- }
1161-
1162- if (result == NULL )
1163- {
1164- /* start merged list with the smaller element */
1165- result_tail = smaller ;
1166- result = smaller ;
1167- }
1168- else
1169- {
1170- /* add smaller element to the list */
1171- result_tail -> next = smaller ;
1172- smaller -> prev = result_tail ;
1173- result_tail = smaller ;
1174- }
1175-
1176- if (first == smaller )
1177- {
1178- first = first -> next ;
1179- }
1180- else
1181- {
1182- second = second -> next ;
1183- }
1184- }
1185-
1186- if (first != NULL )
1187- {
1188- /* Append rest of first list. */
1189- if (result == NULL )
1190- {
1191- return first ;
1192- }
1193- result_tail -> next = first ;
1194- first -> prev = result_tail ;
1195- }
1196- if (second != NULL )
1197- {
1198- /* Append rest of second list */
1199- if (result == NULL )
1200- {
1201- return second ;
1202- }
1203- result_tail -> next = second ;
1204- second -> prev = result_tail ;
1205- }
1206-
1207- return result ;
1217+ sort_object (object , false);
12081218}
12091219
1210- CJSON_PUBLIC (void ) cJSONUtils_SortObject (cJSON * const object )
1220+ CJSON_PUBLIC (void ) cJSONUtils_SortObjectCaseSensitive (cJSON * const object )
12111221{
1212- object -> child = sort_list (object -> child , false );
1222+ sort_object (object , true );
12131223}
12141224
12151225CJSON_PUBLIC (cJSON * ) cJSONUtils_MergePatch (cJSON * target , const cJSON * const patch )
@@ -1262,8 +1272,8 @@ static cJSON *generate_merge_patch(cJSON * const from, cJSON * const to, const c
12621272 return cJSON_Duplicate (to , 1 );
12631273 }
12641274
1265- cJSONUtils_SortObject (from );
1266- cJSONUtils_SortObject (to );
1275+ sort_object (from , case_sensitive );
1276+ sort_object (to , case_sensitive );
12671277
12681278 from_child = from -> child ;
12691279 to_child = to -> child ;
0 commit comments