cJSON_Compare: New function to compare json

This commit is contained in:
Max Bruckner
2017-04-06 13:02:38 +02:00
parent 2a25abbf2a
commit 6ac896d8d2
4 changed files with 298 additions and 0 deletions

101
cJSON.c
View File

@@ -2484,3 +2484,104 @@ CJSON_PUBLIC(cJSON_bool) cJSON_IsRaw(const cJSON * const item)
return (item->type & 0xFF) == cJSON_Raw;
}
CJSON_PUBLIC(cJSON_bool) cJSON_Compare(const cJSON * const a, const cJSON * const b, const cJSON_bool case_sensitive)
{
if ((a == NULL) || (b == NULL) || ((a->type & 0xFF) != (b->type & 0xFF)) || cJSON_IsInvalid(a))
{
return false;
}
/* check if type is valid */
switch (a->type & 0xFF)
{
case cJSON_False:
case cJSON_True:
case cJSON_NULL:
case cJSON_Number:
case cJSON_String:
case cJSON_Raw:
case cJSON_Array:
case cJSON_Object:
break;
default:
return false;
}
/* identical objects are equal */
if (a == b)
{
return true;
}
switch (a->type & 0xFF)
{
/* in these cases and equal type is enough */
case cJSON_False:
case cJSON_True:
case cJSON_NULL:
return true;
case cJSON_Number:
if (a->valuedouble == b->valuedouble)
{
return true;
}
return false;
case cJSON_String:
case cJSON_Raw:
if ((a->valuestring == NULL) || (b->valuestring == NULL))
{
return false;
}
if (strcmp(a->valuestring, b->valuestring) == 0)
{
return true;
}
return false;
case cJSON_Array:
{
cJSON *a_element = NULL;
cJSON *b_element = NULL;
for (a_element = a->child, b_element = b->child;
(a_element != NULL) && (b_element != NULL);
a_element = a_element->next, b_element = b_element->next)
{
if (!cJSON_Compare(a_element, b_element, case_sensitive))
{
return false;
}
}
return true;
}
case cJSON_Object:
{
cJSON *a_element = NULL;
cJSON_ArrayForEach(a_element, a)
{
/* TODO This has O(n^2) runtime, which is horrible! */
cJSON *b_element = get_object_item(b, a_element->string, case_sensitive);
if (b_element == NULL)
{
return false;
}
if (!cJSON_Compare(a_element, b_element, case_sensitive))
{
return false;
}
}
return true;
}
default:
return false;
}
}