Skip to content

Commit 7f22948

Browse files
committed
Add cJSONUtils_SortObjectCaseSensitive
1 parent b674519 commit 7f22948

2 files changed

Lines changed: 127 additions & 116 deletions

File tree

‎cJSON_Utils.c‎

Lines changed: 126 additions & 116 deletions
Original file line numberDiff line numberDiff line change
@@ -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+
428544
static 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

12151225
CJSON_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;

‎cJSON_Utils.h‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,3 +70,4 @@ CJSON_PUBLIC(char *) cJSONUtils_FindPointerFromObjectTo(const cJSON * const obje
7070

7171
/* Sorts the members of the object into alphabetical order. */
7272
CJSON_PUBLIC(void) cJSONUtils_SortObject(cJSON * const object);
73+
CJSON_PUBLIC(void) cJSONUtils_SortObjectCaseSensitive(cJSON * const object);

0 commit comments

Comments
 (0)