mirror of
https://github.com/DaveGamble/cJSON.git
synced 2023-08-10 21:13:26 +03:00
Merge b5d6cfc759
into cb8693b058
This commit is contained in:
commit
0cd4f26522
5
cJSON.c
5
cJSON.c
@ -2201,6 +2201,11 @@ CJSON_PUBLIC(cJSON *) cJSON_DetachItemViaPointer(cJSON *parent, cJSON * const it
|
||||
/* not the last element */
|
||||
item->next->prev = item->prev;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* the last element - need to fix the prev pointer of the 1st element */
|
||||
parent->child->prev = item->prev;
|
||||
}
|
||||
|
||||
if (item == parent->child)
|
||||
{
|
||||
|
@ -480,8 +480,23 @@ cleanup:
|
||||
return detached_item;
|
||||
}
|
||||
|
||||
static int compare_json_string(const cJSON * const a, const cJSON * const b, const cJSON_bool case_sensitive)
|
||||
{
|
||||
return compare_strings((unsigned char*)a->string, (unsigned char*)b->string, case_sensitive);
|
||||
}
|
||||
|
||||
static int compare_json_string_case_sensitive(const cJSON * const a, const cJSON * const b)
|
||||
{
|
||||
return compare_json_string(a, b, true);
|
||||
}
|
||||
|
||||
static int compare_json_string_case_insensitive(const cJSON * const a, const cJSON * const b)
|
||||
{
|
||||
return compare_json_string(a, b, false);
|
||||
}
|
||||
|
||||
/* sort lists using mergesort */
|
||||
static cJSON *sort_list(cJSON *list, const cJSON_bool case_sensitive)
|
||||
static cJSON *sort_list(cJSON *list, int (*compar)(const cJSON * const a, const cJSON * const b))
|
||||
{
|
||||
cJSON *first = list;
|
||||
cJSON *second = list;
|
||||
@ -495,7 +510,7 @@ static cJSON *sort_list(cJSON *list, const cJSON_bool case_sensitive)
|
||||
return result;
|
||||
}
|
||||
|
||||
while ((current_item != NULL) && (current_item->next != NULL) && (compare_strings((unsigned char*)current_item->string, (unsigned char*)current_item->next->string, case_sensitive) < 0))
|
||||
while ((current_item != NULL) && (current_item->next != NULL) && (compar(current_item, current_item->next) < 0))
|
||||
{
|
||||
/* Test for list sorted. */
|
||||
current_item = current_item->next;
|
||||
@ -527,15 +542,15 @@ static cJSON *sort_list(cJSON *list, const cJSON_bool case_sensitive)
|
||||
}
|
||||
|
||||
/* Recursively sort the sub-lists. */
|
||||
first = sort_list(first, case_sensitive);
|
||||
second = sort_list(second, case_sensitive);
|
||||
first = sort_list(first, compar);
|
||||
second = sort_list(second, compar);
|
||||
result = NULL;
|
||||
|
||||
/* Merge the sub-lists */
|
||||
while ((first != NULL) && (second != NULL))
|
||||
{
|
||||
cJSON *smaller = NULL;
|
||||
if (compare_strings((unsigned char*)first->string, (unsigned char*)second->string, case_sensitive) < 0)
|
||||
if (compar(first, second) < 0)
|
||||
{
|
||||
smaller = first;
|
||||
}
|
||||
@ -598,7 +613,13 @@ static void sort_object(cJSON * const object, const cJSON_bool case_sensitive)
|
||||
{
|
||||
return;
|
||||
}
|
||||
object->child = sort_list(object->child, case_sensitive);
|
||||
if (case_sensitive) {
|
||||
object->child = sort_list(object->child, compare_json_string_case_sensitive);
|
||||
}
|
||||
else
|
||||
{
|
||||
object->child = sort_list(object->child, compare_json_string_case_insensitive);
|
||||
}
|
||||
}
|
||||
|
||||
static cJSON_bool compare_json(cJSON *a, cJSON *b, const cJSON_bool case_sensitive)
|
||||
@ -1479,3 +1500,12 @@ CJSON_PUBLIC(cJSON *) cJSONUtils_GenerateMergePatchCaseSensitive(cJSON * const f
|
||||
{
|
||||
return generate_merge_patch(from, to, true);
|
||||
}
|
||||
|
||||
CJSON_PUBLIC(void) cJSONUtils_SortArray(cJSON * const array, int (*compar)(const cJSON * const a, const cJSON * const b))
|
||||
{
|
||||
if ((array == NULL) || (array->child == NULL) || (2 > cJSON_GetArraySize(array))) {
|
||||
return;
|
||||
}
|
||||
array->child = sort_list(array->child, compar);
|
||||
}
|
||||
|
||||
|
@ -81,6 +81,12 @@ CJSON_PUBLIC(char *) cJSONUtils_FindPointerFromObjectTo(const cJSON * const obje
|
||||
CJSON_PUBLIC(void) cJSONUtils_SortObject(cJSON * const object);
|
||||
CJSON_PUBLIC(void) cJSONUtils_SortObjectCaseSensitive(cJSON * const object);
|
||||
|
||||
/* Sort the members of the array according to the provided comparison function. */
|
||||
/* The comparison function must return an integer that shows if the first */
|
||||
/* argument is considered less than (< 0), equals to (0) or greater than (> 0) */
|
||||
/* the second argument. */
|
||||
CJSON_PUBLIC(void) cJSONUtils_SortArray(cJSON * const object, int (*compar)(const cJSON * const a, const cJSON * const b));
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
@ -97,7 +97,8 @@ if(ENABLE_CJSON_TEST)
|
||||
set (cjson_utils_tests
|
||||
json_patch_tests
|
||||
old_utils_tests
|
||||
misc_utils_tests)
|
||||
misc_utils_tests
|
||||
sort_utils_tests)
|
||||
|
||||
foreach (cjson_utils_test ${cjson_utils_tests})
|
||||
add_executable("${cjson_utils_test}" "${cjson_utils_test}.c")
|
||||
|
112
tests/sort_utils_tests.c
Normal file
112
tests/sort_utils_tests.c
Normal file
@ -0,0 +1,112 @@
|
||||
/*
|
||||
Copyright (c) 2009-2017 Dave Gamble and cJSON contributors
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "unity/examples/unity_config.h"
|
||||
#include "unity/src/unity.h"
|
||||
#include "common.h"
|
||||
#include "../cJSON_Utils.h"
|
||||
|
||||
static int cmp(const double *a, const double *b) {
|
||||
if (*a > *b)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
if (*a < *b)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int jcmp_double(const cJSON *a, const cJSON *b)
|
||||
{
|
||||
return cmp(&(a->valuedouble), &(b->valuedouble));
|
||||
}
|
||||
|
||||
static void cjson_utils_sort_null(void)
|
||||
{
|
||||
cJSON *empty = NULL;
|
||||
cJSONUtils_SortArray(empty, jcmp_double);
|
||||
TEST_ASSERT_NULL(empty);
|
||||
}
|
||||
|
||||
static void cjson_utils_sort_empty(void)
|
||||
{
|
||||
cJSON *array = cJSON_CreateArray();
|
||||
cJSONUtils_SortArray(array, jcmp_double);
|
||||
TEST_ASSERT_EQUAL_INT(0, cJSON_GetArraySize(array));
|
||||
cJSON_Delete(array);
|
||||
}
|
||||
|
||||
static void cjson_utils_sort_size1(void)
|
||||
{
|
||||
double d[1] = {0.0};
|
||||
cJSON *array = cJSON_CreateDoubleArray(d, 1);
|
||||
cJSONUtils_SortArray(array, jcmp_double);
|
||||
TEST_ASSERT_EQUAL_INT(1, cJSON_GetArraySize(array));
|
||||
cJSON_Delete(array);
|
||||
}
|
||||
|
||||
static void cjson_utils_sort_double_issorted(void)
|
||||
{
|
||||
size_t size = 8192;
|
||||
size_t i;
|
||||
cJSON *array, *elt, *prev;
|
||||
double *d;
|
||||
|
||||
/* generate array with rand doubles */
|
||||
d = (double*)malloc(size * sizeof(double));
|
||||
for (i = 0; i < size; i++)
|
||||
{
|
||||
d[i] = (double)rand();
|
||||
}
|
||||
array = cJSON_CreateDoubleArray(d, (int)size);
|
||||
cJSONUtils_SortArray(array, jcmp_double);
|
||||
TEST_ASSERT_EQUAL_INT(size, cJSON_GetArraySize(array));
|
||||
|
||||
/* check if order is achieved */
|
||||
prev = NULL;
|
||||
cJSON_ArrayForEach(elt, array)
|
||||
{
|
||||
if (prev != NULL) {
|
||||
TEST_ASSERT_LESS_THAN_INT(1, jcmp_double(prev, elt));
|
||||
}
|
||||
prev = elt;
|
||||
}
|
||||
cJSON_Delete(array);
|
||||
}
|
||||
|
||||
int main(void)
|
||||
{
|
||||
UNITY_BEGIN();
|
||||
|
||||
RUN_TEST(cjson_utils_sort_null);
|
||||
RUN_TEST(cjson_utils_sort_empty);
|
||||
RUN_TEST(cjson_utils_sort_size1);
|
||||
RUN_TEST(cjson_utils_sort_double_issorted);
|
||||
|
||||
return UNITY_END();
|
||||
}
|
Loading…
Reference in New Issue
Block a user