Esempio n. 1
0
int json_equal(json_t *json1, json_t *json2)
{
    if(!json1 || !json2)
        return 0;

    if(json_typeof(json1) != json_typeof(json2))
        return 0;

    /* this covers true, false and null as they are singletons */
    if(json1 == json2)
        return 1;

    if(json_is_object(json1))
        return json_object_equal(json1, json2);

    if(json_is_array(json1))
        return json_array_equal(json1, json2);

    if(json_is_string(json1))
        return json_string_equal(json1, json2);

    if(json_is_integer(json1))
        return json_integer_equal(json1, json2);

    if(json_is_real(json1))
        return json_real_equal(json1, json2);

    return 0;
}
Esempio n. 2
0
json_t *json_true(void)
{
    static json_t the_true = {
        .type = JSON_TRUE,
        .refcount = (unsigned int)1
    };
    return &the_true;
}


json_t *json_false(void)
{
    static json_t the_false = {
        .type = JSON_FALSE,
        .refcount = (unsigned int)1
    };
    return &the_false;
}


json_t *json_null(void)
{
    static json_t the_null = {
        .type = JSON_NULL,
        .refcount = (unsigned int)1
    };
    return &the_null;
}


/*** deletion ***/

void json_delete(json_t *json)
{
    if(json_is_object(json))
        json_delete_object(json_to_object(json));

    else if(json_is_array(json))
        json_delete_array(json_to_array(json));

    else if(json_is_string(json))
        json_delete_string(json_to_string(json));

    else if(json_is_integer(json))
        json_delete_integer(json_to_integer(json));

    else if(json_is_real(json))
        json_delete_real(json_to_real(json));

    /* json_delete is not called for true, false or null */
}


/*** equality ***/

int json_equal(json_t *json1, json_t *json2)
{
    if(!json1 || !json2)
        return 0;

    if(json_typeof(json1) != json_typeof(json2))
        return 0;

    /* this covers true, false and null as they are singletons */
    if(json1 == json2)
        return 1;

    if(json_is_object(json1))
        return json_object_equal(json1, json2);

    if(json_is_array(json1))
        return json_array_equal(json1, json2);

    if(json_is_string(json1))
        return json_string_equal(json1, json2);

    if(json_is_integer(json1))
        return json_integer_equal(json1, json2);

    if(json_is_real(json1))
        return json_real_equal(json1, json2);

    return 0;
}


/*** copying ***/

json_t *json_copy(json_t *json)
{
    if(!json)
        return NULL;

    if(json_is_object(json))
        return json_object_copy(json);

    if(json_is_array(json))
        return json_array_copy(json);

    if(json_is_string(json))
        return json_string_copy(json);

    if(json_is_integer(json))
        return json_integer_copy(json);

    if(json_is_real(json))
        return json_real_copy(json);

    if(json_is_true(json) || json_is_false(json) || json_is_null(json))
        return json;

    return NULL;
}

json_t *json_deep_copy(json_t *json)
{
    if(!json)
        return NULL;

    if(json_is_object(json))
        return json_object_deep_copy(json);

    if(json_is_array(json))
        return json_array_deep_copy(json);

    /* for the rest of the types, deep copying doesn't differ from
       shallow copying */

    if(json_is_string(json))
        return json_string_copy(json);

    if(json_is_integer(json))
        return json_integer_copy(json);

    if(json_is_real(json))
        return json_real_copy(json);

    if(json_is_true(json) || json_is_false(json) || json_is_null(json))
        return json;

    return NULL;
}
Esempio n. 3
0
int main()
{
	/* integer tests */
	struct json_object *int1 = json_object_new_int(0);
	struct json_object *int2 = json_object_new_int(1);
	struct json_object *int3 = json_object_new_int(1);

	if (!json_object_equal(int1, int2))
		printf("JSON integer comparision is correct\n");
	else
		printf("JSON integer comparision failed\n");

	if (json_object_equal(int1, int1))
		printf("JSON same object comparision is correct\n");
	else
		printf("JSON same object comparision failed\n");

	if (json_object_equal(int2, int3))
		printf("JSON same integer comparision is correct\n");
	else
		printf("JSON same integer comparision failed\n");

	json_object_put(int1);
	json_object_put(int2);
	json_object_put(int3);

	/* string tests */
	struct json_object *str1 = json_object_new_string("TESTSTRING");
	struct json_object *str2 = json_object_new_string("TESTSTRING");
	struct json_object *str3 = json_object_new_string("DIFFERENT");

	if (json_object_equal(str1, str2))
		printf("Comparing equal strings is correct\n");
	else
		printf("Comparing equal strings failed\n");

	if (!json_object_equal(str1, str3))
		printf("Comparing different strings is correct\n");
	else
		printf("Comparing different strings failed\n");

	json_object_put(str1);
	json_object_put(str2);
	json_object_put(str3);

	/* double tests */
	struct json_object *dbl1 = json_object_new_double(3.14159);
	struct json_object *dbl2 = json_object_new_double(3.14159);
	struct json_object *dbl3 = json_object_new_double(3.0);

	if (json_object_equal(dbl1, dbl2))
		printf("Comparing equal doubles is correct\n");
	else
		printf("Comparing equal doubles failed\n");

	if (!json_object_equal(dbl1, dbl3))
		printf("Comparing different doubles is correct\n");
	else
		printf("Comparing different doubles failed\n");

	json_object_put(dbl1);
	json_object_put(dbl2);
	json_object_put(dbl3);

	/* array tests */
	struct json_object *ar1 = json_object_new_array();
	struct json_object *ar2 = json_object_new_array();
	struct json_object *ar3 = json_object_new_array();
	struct json_object *ar4 = json_object_new_array();

	json_object_array_add(ar1, json_object_new_int(1));
	json_object_array_add(ar1, json_object_new_int(2));

	json_object_array_add(ar2, json_object_new_int(1));
	json_object_array_add(ar2, json_object_new_int(2));

	json_object_array_add(ar3, json_object_new_int(1));
	json_object_array_add(ar3, json_object_new_int(1));

	if (json_object_equal(ar1, ar2))
		printf("Comparing equal arrays is correct\n");
	else
		printf("Comparing equal arrays failed\n");

	json_object_array_add(ar2, json_object_new_int(1));
	if (!json_object_equal(ar1, ar2))
		printf("Comparing arrays of different len is correct\n");
	else
		printf("Comparing arrays of different len failed\n");

	if (!json_object_equal(ar1, ar3))
		printf("Comparing different arrays is correct\n");
	else
		printf("Comparing different arrays failed\n");

	if (!json_object_equal(ar1, ar4))
		printf("Comparing different arrays (one empty) is correct\n");
	else
		printf("Comparing different arrays (one empty) failed\n");

	json_object_put(ar1);
	json_object_put(ar2);
	json_object_put(ar3);
	json_object_put(ar4);

	/* object tests */
	struct json_object *obj1 = json_object_new_object();
	struct json_object *obj2 = json_object_new_object();

	json_object_object_add(obj1, "test1", json_object_new_int(123));
	json_object_object_add(obj1, "test2", json_object_new_int(321));

	json_object_object_add(obj2, "test2", json_object_new_int(123));
	json_object_object_add(obj2, "test1", json_object_new_int(321));

	/* key-order is different between obj1 and obj2, should still be equal */
	if (json_object_equal(obj1, obj2))
		printf("Comparing JSON object with different key order is correct\n");
	else
		printf("Comparing JSON object with different key order is incorrect\n");

	/* make obj2 look different to obj1 */
	json_object_object_add(obj2, "test3", json_object_new_int(234));
	if (!json_object_equal(obj1, obj2))
		printf("Comparing different objects is correct\n");
	else
		printf("Comparing different objects is incorrect\n");

	json_object_put(obj1);
	json_object_put(obj2);

	return 0;
}
Esempio n. 4
0
/**
 * json_node_equal:
 * @a: (type JsonNode): a JSON node
 * @b: (type JsonNode): another JSON node
 *
 * Check whether @a and @b are equal #JsonNodes, meaning they have the same
 * type and same values (checked recursively). Note that integer values are
 * compared numerically, ignoring type, so a double value 4.0 is equal to the
 * integer value 4.
 *
 * Returns: %TRUE if @a and @b are equal; %FALSE otherwise
 * Since: 1.2
 */
gboolean
json_node_equal (gconstpointer  a,
                 gconstpointer  b)
{
  JsonNode *node_a, *node_b;  /* unowned */

  node_a = (JsonNode *) a;
  node_b = (JsonNode *) b;

  /* Identity comparison. */
  if (node_a == node_b)
    return TRUE;

  /* Eliminate mismatched types rapidly. */
  if (!json_type_is_a (node_a, node_b) &&
      !json_type_is_a (node_b, node_a))
    {
      return FALSE;
    }

  switch (node_a->type)
    {
    case JSON_NODE_NULL:
      /* Types match already. */
      return TRUE;
    case JSON_NODE_ARRAY:
      return json_array_equal (json_node_get_array (node_a),
                               json_node_get_array (node_b));
    case JSON_NODE_OBJECT:
      return json_object_equal (json_node_get_object (node_a),
                                json_node_get_object (node_b));
    case JSON_NODE_VALUE:
      /* Handled below. */
      break;
    default:
      g_assert_not_reached ();
    }

  /* Handle values. */
  switch (node_a->data.value->type)
    {
    case JSON_VALUE_NULL:
      /* Types already match. */
      return TRUE;
    case JSON_VALUE_BOOLEAN:
      return (json_node_get_boolean (node_a) == json_node_get_boolean (node_b));
    case JSON_VALUE_STRING:
      return json_string_equal (json_node_get_string (node_a),
                                json_node_get_string (node_b));
    case JSON_VALUE_DOUBLE:
    case JSON_VALUE_INT: {
      gdouble val_a, val_b;
      JsonValueType value_type_a, value_type_b;

      value_type_a = node_a->data.value->type;
      value_type_b = node_b->data.value->type;

      /* Integer comparison doesn’t need to involve doubles… */
      if (value_type_a == JSON_VALUE_INT &&
          value_type_b == JSON_VALUE_INT)
        {
          return (json_node_get_int (node_a) ==
                  json_node_get_int (node_b));
        }

      /* …but everything else does. We can use bitwise double equality here,
       * since we’re not doing any calculations which could introduce floating
       * point error. We expect that the doubles in the JSON nodes come directly
       * from strtod() or similar, so should be bitwise equal for equal string
       * representations.
       *
       * Interesting background reading:
       * http://randomascii.wordpress.com/2012/06/26/\
       *   doubles-are-not-floats-so-dont-compare-them/
       */
      if (value_type_a == JSON_VALUE_INT)
        val_a = json_node_get_int (node_a);
      else
        val_a = json_node_get_double (node_a);

      if (value_type_b == JSON_VALUE_INT)
        val_b = json_node_get_int (node_b);
      else
        val_b = json_node_get_double (node_b);

      return (val_a == val_b);
    }
    case JSON_VALUE_INVALID:
    default:
      g_assert_not_reached ();
    }
}